數據操縱:SELECT, INSERT, UPDATE, DELETE

来源:http://www.cnblogs.com/cykj/archive/2017/04/05/Data-manipulation-SELECT-INSERT-UPDATE-DELETE.html
-Advertisement-
Play Games

數據操縱:SELECT, INSERT, UPDATE, DELETE ...


  1 SELECT 句法
  2 
  3 SELECT [STRAIGHT_JOIN]
  4        [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
  5        [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
  6        [DISTINCT | DISTINCTROW | ALL]
  7     select_expression,...
  8     [INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
  9     [FROM table_references
 10       [WHERE where_definition]
 11       [GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
 12       [HAVING where_definition]
 13       [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
 14       [LIMIT [offset,] rows | rows OFFSET offset]
 15       [PROCEDURE procedure_name(argument_list)]
 16       [FOR UPDATE | LOCK IN SHARE MODE]]
 17 
 18 SELECT 用於檢索從一個或多個表中選取出的行。select_expression 表示你希望檢索的列。 SELECT 也可以被用於檢索沒有引用任何表的計算列。例如: 
 19 
 20 mysql> SELECT 1 + 1;
 21          -> 2
 22 
 23 所有使用的關鍵詞必須嚴格以上面所顯示的次序被給出。舉例來說,一個 HAVING 子句必須出現在 GROUP BY 子句後,在 ORDER BY 字句之前。 
 24 
 25 一個 SELECT 表達式可以使用 AS 指定一個別名。別名可以當作表達式的列名,用於 ORDER BYHAVING 子句中。例如: 
 26 mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name
 27     FROM mytable ORDER BY full_name;
 28 
 29 在一個 WHERE 子句中使用一個列別名是不允許的,因為,當 WHERE 子句被執行時,列值可能還沒有被計算確定。查看章節 A.5.4 使用 alias 的限制。 
 30 
 31 FROM table_references 子句表示從哪個表中檢索記錄行。如果你命名超過超過一個表,並執行一個 join。對於 join 句法的信息,查看章節 6.4.1.1 JOIN 句法。對於每個引用的表,你可以順便指定一個別名。 
 32 table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | FORCE INDEX (key_list)]]
 33 
 34 到 MySQL 3.23.12 時,當 MySQL 在從一個表中檢索信息時,你可以提示它選擇了哪一個索引。如果 EXPLAIN 顯示 MySQL 使用了可能的索引列表中錯誤的索引,這個特性將是很有用的。通過指定 USE INDEX (key_list),你可以告訴 MySQL 使用可能的索引中最合適的一個索引在表中查找記錄行。可選的二選一句法 IGNORE INDEX (key_list) 可被用於告訴 MySQL 不使用特定的索引。 在 MySQL 4.0.9 中,你也可以使用 FORCE INDEX。這個有點像 USE INDEX (key_list),但是有了這個附加物,一個表的掃描被採用時,將會有非常大的開銷。換句法說,如果沒有方法使用給定的索引在表中尋找記錄行,這時表掃描才會被使用。 USE/IGNORE/FORCE KEY 分別是 USE/IGNORE/FORCE INDEX 的同義詞。 
 35 
 36 你可以以 tbl_name (在當前的資料庫中) 引用一張表,或以 dbname.tbl_name 明確地指定其個數據。你要以以 col_name、tbl_name.col_namedb_name.tbl_name.col_name 引用一個列。 你不需要在一個 SELECT 語句中引用的列前指定 tbl_name 或 db_name.tbl_name 首碼,除非引用列存在二義性。查看章節 6.1.2 資料庫、表、索引、列和別名,對於有歧義的列引用需要更加顯式的列引用格式。 
 37 
 38 一個表的引用可以使用 tbl_name [AS] alias_name 給以別名: 
 39 mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
 40     ->        WHERE t1.name = t2.name;
 41 mysql> SELECT t1.name, t2.salary FROM employee t1, info t2
 42     ->        WHERE t1.name = t2.name;
 43 
 44 選取出來用於輸出的列可以在 ORDER BYGROUP BY 子句中使用列名、列的別名或列的位置來引用。列的位置從 1 開始: 
 45 mysql> SELECT college, region, seed FROM tournament
 46     ->        ORDER BY region, seed;
 47 mysql> SELECT college, region AS r, seed AS s FROM tournament
 48     ->        ORDER BY r, s;
 49 mysql> SELECT college, region, seed FROM tournament
 50     ->        ORDER BY 2, 3;
 51 
 52 為了以倒序排序,可以在 ORDER BY 子句中用於排序的列名後添加一個 DESC (遞減 descending)關鍵詞。預設為升序排序;這也可以通過使用 ASC 關鍵詞明確指定。 
 53 
 54WHERE 子句中可以使用 MySQL 支持的任何函數。查看章節 6.3 用於 SELECTWHERE 子句的函數。 
 55 
 56 HAVING 子句可以引用任何列或在 select_expression 中命名的別名。它在最後被執行,僅僅就在項目被送到客戶端之前,不進行任何優化。所以不要對應該放在 WHERE 子句中的項目使用 HAVING。舉例來說,不要寫成這樣: 
 57 mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;
 58 
 59 用這個代替: 
 60 mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;
 61 
 62 在 MySQL 3.22.5 或以後的版本中,你也可以這下麵的形式書寫一個查詢: 
 63 mysql> SELECT user,MAX(salary) FROM users
 64     ->        GROUP BY user HAVING MAX(salary)>10;
 65 
 66 在較早的 MySQL 版本中,你可能需要用下麵的代替了: 
 67 mysql> SELECT user,MAX(salary) AS sum FROM users
 68     ->        group by user HAVING sum>10;
 69 
 70 DISTINCT、DISTINCTROW 和 ALL 選項指定重覆的記錄行是否被返回。預設為 (ALL),返回所有匹配的記錄行。DISTINCT 和 DISTINCTROW 是同義詞,它指定結果集重覆的記錄行被排除。 
 71 
 72 所有以 SQL_ 開頭、STRAIGHT_JOIN 和 HIGH_PRIORITY 的選項是 MySQL 對 ANSI SQL 的擴展。 
 73 
 74 HIGH_PRIORITY 將給 SELECT 語句比更新一個表有更高的優先順序。你只應該對非常快的或需要立即返回的查詢使用它。 如果一個表已被讀鎖定,甚至是有一個更新語句正在等待表的釋放,一個 SELECT HIGH_PRIORITY 查詢也將會執行。 
 75 
 76 SQL_BIG_RESULT 可以與 GROUP BYDISTINCT 一同使用,以告訴優化器結果集將有許多記錄行。在這種情況下,如果需要,MySQL 將直接使用基於磁碟的臨時表。同樣的,在這種情況下,MySQL 更願意以 GROUP BY 上的一個鍵進行排序而不是建立一個臨時表。 
 77 
 78 SQL_BUFFER_RESULT 將強制把結果放入一個臨時表。這將有助於 MySQL 儘早地釋放表和有助於將大的結果集傳送到客戶端。 
 79 
 80 SQL_SMALL_RESULT, 一個 MySQL 特有的選項,可以與 GROUP BYDISTINCT 一同使用,以告訴優化器結果集將會很小。在這種情況下,MySQL 將使用快速的臨時表存儲結果表,而不是使用排序。在 MySQL 3.23 中,這通常是不需要的。 
 81 
 82 SQL_CALC_FOUND_ROWS (版本 4.0.0 和更新的) 告訴 MySQL 計算在不考慮 LIMIT 子句時結果集中將有多少行記錄。然後使用 SELECT FOUND_ROWS() 可以檢索到記錄行的數目。查看章節 6.3.6.2 輔助功能函數。 請註意,在早於 4.1.0 的版本中,LIMIT 0 是不工作的,它將被優化為立即返回(結果集的記錄數為 0)。查看章節 5.2.8 MySQL 如何優化 LIMIT。 
 83 
 84 如果你使用了 QUERY_CACHE_TYPE=2 (DEMAND),SQL_CACHE 告訴 MySQL 將存儲查詢結果放入查詢高速緩存內。查看章節 6.9 MySQL 的查詢高速緩存。 
 85 
 86 SQL_NO_CACHE 告訴 MySQL 不允許將查詢結果存儲到查詢緩存內。查看章節 6.9 MySQL 的查詢高速緩存。 
 87 
 88 如果使用了 GROUP BY,輸出記錄將會依照 GROUP BY 列進行排序,就好像你對所有 GROUP BY 中的所有欄位使用了 ORDER BY。MySQL 擴展了 GROUP BY 的用法,所以你也可以在 GROUP BY 中指定 ASCDESC 89 SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
 90 
 91 MySQL 擴展了的 GROUP BY 用法允許你選取沒有在 GROUP BY 子句中提及的欄位。如果你的查詢沒有得到你所期望的結果,請查看 GROUP BY 中的描述。查看章節 6.3.7 用於 GROUP BY 子句的函數。 
 92 
 93 STRAIGHT_JOIN 強制優化器以表在 FROM 子句中列出的順序聯結。如果優化器以一個非優化的次序聯結各表,你可以使用它來加速一個查詢。查看章節 5.2.1 EXPLAIN 句法(得到有關 SELECT 的信息)。 
 94 
 95 LIMIT 子句可以被用於強制 SELECT 語句返回指定的記錄數。LIMIT 接受一個或兩個數字參數。參數必須是一個整數常量。如果給定兩個參數,第一個參數指定第一個返回記錄行的偏移量,第二個參數指定返回記錄行的最大數目。初始記錄行的偏移量是 0(而不是 1): 為了與 PostgreSQL 相容,MySQL 也支持句法: LIMIT # OFFSET #。 
 96 mysql> SELECT * FROM table LIMIT 5,10;  # 檢索記錄行 6-15
 97 
 98 為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個參數為 -1 99 mysql> SELECT * FROM table LIMIT 95,-1; # 檢索記錄行 96-last.
100 
101 如果只給定一個參數,它表示返回最大的記錄行數目: 
102 mysql> SELECT * FROM table LIMIT 5;     # 檢索前 5 個記錄行
103 
104 換句話說,LIMIT n 等價於 LIMIT 0,n。 
105 
106 SELECT ... INTO OUTFILE 'file_name' 格式的 SELECT 將選擇的記錄行寫入一個文件。文件被建立在伺服器主機上,並且不可以是已存在的 (不管別的,這可以防止資料庫表和文件例如 `/etc/passwd' 被破壞)。你必須在伺服器主機上有 FILE 許可權來使用這個形式的 SELECT。 SELECT ... INTO OUTFILE 主要是有意於讓你能夠在服務主機上快速地轉儲一個表。如果你希望將結果文件建立在其它的主機上,而不是伺服器上,你就不能使用 SELECT ... INTO OUTFILE。在這種情況下,你應該使用某些客戶端程式例如 mysqldump --tab 或 mysql -e "SELECT ..." > outfile 產生文件來代替它。 SELECT ... INTO OUTFILE 是 LOAD DATA INFILE 的逆操作;語句中的 export_options 部分的句法由 FIELDS 和 LINES 子句組成,它們與與用在 LOAD DATA INFILE 語句中的相同。查看章節 6.4.9 LOAD DATA INFILE 句法。 在結果文本文件中,只有下列的字元被 ESCAPED BY 指定的字元轉義: 
107 ESCAPED BY 字元 
108 在 FIELDS TERMINATED BY 中的第一個字元 
109 在 LINES TERMINATED BY 中的第一個字元 
110 另外,ASCII 0 被轉換到 ESCAPED BY 後而跟一個 0 (ASCII 48)。 上述行為的原因是,你必須 轉義任何 FIELDS TERMINATED BY、ESCAPED BY 或LINES TERMINATED BY 字元,以便能可靠地將文件讀回。ASCII 0 被轉義是為了更容易地使用某些分頁程式查看它。 因為結果文件並不需要遵從 SQL 句法,所以其它是不需要轉義。 下麵的例子得到的文件是可用於許多老程式的格式。 
111 SELECT a,b,a+b INTO OUTFILE "/tmp/result.text"
112 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
113 LINES TERMINATED BY "\n"
114 FROM test_table;
115 
116 如果使用 INTO DUMPFILE 代替 INTO OUTFILE,MySQL 將在文件中只寫一行,沒任何列或行端接和任何轉義。如果你希望存儲一個 blob 列到文件中,這是非常有用的。 
117 註意,任何由 INTO OUTFILE 和 INTO DUMPFILE 創建的文件將被所有用戶可讀寫!原因是, MySQL 伺服器不能夠創建一個其他用戶擁有的文件,(你決不應該以 root 身份運行 mysqld),該文件必須是公共可讀寫的,以便於你能操作它。 
118 
119 如果你以頁/行鎖使用在一個存儲引擎上 FOR UPDATE,被檢索的記錄行將被寫鎖。 
120 6.4.1.1 JOIN 句法
121 
122 MySQL 支持在 SELECT 中使用下麵所示的 JOIN 句法: 
123 
124 table_reference, table_reference
125 table_reference [CROSS] JOIN table_reference
126 table_reference INNER JOIN table_reference join_condition
127 table_reference STRAIGHT_JOIN table_reference
128 table_reference LEFT [OUTER] JOIN table_reference join_condition
129 table_reference LEFT [OUTER] JOIN table_reference
130 table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
131 { OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr }
132 table_reference RIGHT [OUTER] JOIN table_reference join_condition
133 table_reference RIGHT [OUTER] JOIN table_reference
134 table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
135 
136 table_reference 定義如下: 
137 
138 table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]
139 
140 join_condition 定義如下: 
141 
142 ON conditional_expr |
143 USING (column_list)
144 
145 通常不應該在 ON 存在任何條件式,它是用於限制在結果集中有哪個行的(對於這個規則也有例外)。如果你希望哪個記錄行應該在結果中,你必須在 WHERE 子句中限制它。 
146 
147 註意,在早於 3.23.17 的版本中,INNER JOIN 不接受一個 join_condition! 
148 
149 上面所顯示的最後一個 LEFT OUTER JOIN 句法僅僅是為了與 ODBC 相容而存在的: 
150 
151 一個表引用可以使用 tbl_name AS alias_name 或 tbl_name alias_name 命以別名: 
152 mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
153     ->        WHERE t1.name = t2.name;
154 
155 ON 條件是可以用在一個 WHERE 子句中的任何形式的條件。 
156 
157 如果在一個 LEFT JOIN 的 ON 或 USING 部分中右表沒有匹配的記錄,一個所有列被設置為 NULL 的記錄行將被用於右表。你可以通過這個行為找到一個表在另一個表中沒有配對物的記錄: 
158 mysql> SELECT table1.* FROM table1
159     ->        LEFT JOIN table2 ON table1.id=table2.id
160     ->        WHERE table2.id IS NULL;
161 
162 這個例子在 table1 中找到所有的記錄行,其 id 值沒有出現在 table2 中(即,所有在 table1 存在的,但在 table2 中沒有對應記錄的記錄行)。當然,這是假定 table2.id 被聲明為 NOT NULL 的。查看章節 5.2.6 MySQL 如何優化 LEFT JOIN 和 RIGHT JOIN。 
163 
164 USING (column_list) 子句指定了一個列的列表,列表的中列必須同時存在於兩個表中。例如 USING 子句如下所示: 
165 A LEFT JOIN B USING (C1,C2,C3,...)
166 
167 它可以被定義為在語義上等同於一個這樣的 ON 表達式: 
168 A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
169 
170 兩個表的 NATURAL [LEFT] JOIN 被定義為在語義上等同於使用了 USING 子句指定存在於兩張表中的所有列的一個 INNER JOIN 或一個 LEFT JOIN。 
171 
172 INNER JOIN 和 , (逗號) 在語義上是等同的。都是在所有的表之間進行一個全聯結。通常,在 WHERE 條件中指定表應該如何聯結。 
173 
174 RIGHT JOIN 作用類似於 LEFT JOIN。為了保持資料庫邊的代碼上精簡,LEFT JOIN 被推薦使用來代替 RIGHT JOIN。 
175 
176 STRAIGHT_JOIN 等同於 JOIN,除了左表先於右表被讀入。當聯結優化器將表的順序放錯時(很少),這可用於這種情況。 
177 
178 到 MySQL 3.23.12 時,當 MySQL 在從一個表中檢索信息時,你可以提示它選擇了哪一個索引。如果 EXPLAIN 顯示 MySQL 使用了可能的索引列表中錯誤的索引,這個特性將是很有用的。通過指定 USE INDEX (key_list),你可以告訴 MySQL 使用可能的索引中最合適的一個索引在表中查找記錄行。可選的二選一句法 IGNORE INDEX (key_list) 可被用於告訴 MySQL 不使用特定的索引。 在 MySQL 4.0.9 中,你也可以使用 FORCE INDEX。這個有點像 USE INDEX (key_list),但是有了這個附加物,一個表的掃描被採用時,將會有非常大的開銷。換句法說,如果沒有方法使用給定的索引在表中尋找記錄行,這時表掃描才會被使用。 USE/IGNORE/FORCE KEY 分別是 USE/IGNORE/FORCE INDEX 的同義詞。 
179 一些例子: 
180 
181 mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id;
182 mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;
183 mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id);
184 mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id
185     ->          LEFT JOIN table3 ON table2.id=table3.id;
186 mysql> SELECT * FROM table1 USE INDEX (key1,key2)
187     ->          WHERE key1=1 AND key2=2 AND key3=3;
188 mysql> SELECT * FROM table1 IGNORE INDEX (key3)
189     ->          WHERE key1=1 AND key2=2 AND key3=3;
190 
191 查看章節 5.2.6 MySQL 如何優化 LEFT JOIN 和 RIGHT JOIN。 
192 
193 6.4.1.2 UNION 句法
194 
195 SELECT ...
196 UNION [ALL]
197 SELECT ...
198   [UNION
199    SELECT ...]
200 
201 UNION 在 MySQL 4.0.0 中被實現。 
202 
203 UNION 用於將多個 SELECT 語句的結果聯合到一個結果集中。 
204 
205 在 SELECT 中的 select_expression 部分列出的列必須具有同樣的類型。第一個 SELECT 查詢中使用的列名將作為結果集的列名返回。 
206 
207 SELECT 命令是一個普通的選擇命令,但是有下列的限制: 
208 
209 只有最後一個 SELECT 命令可以有 INTO OUTFILE。 
210 如果你不為 UNION 使用關鍵詞 ALL,所有返回的記錄行將是唯一的,就好像你為整個返回集使用了一個 DISTINCT。如果你指定了 ALL,那麼你將得到從所有使用的 SELECT 語句中返回的所有匹配記錄行。 
211 
212 如果你希望對整個 UNION 結果使用一個 ORDER BY,你應該使用圓括弧: 
213 
214 (SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
215 UNION
216 (SELECT a FROM table_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10)
217 ORDER BY a;
218 
219 
220 6.4.2 HANDLER 句法
221 HANDLER tbl_name OPEN [ AS alias ]
222 HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...)
223     [ WHERE ... ] [LIMIT ... ]
224 HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
225     [ WHERE ... ] [LIMIT ... ]
226 HANDLER tbl_name READ { FIRST | NEXT }
227     [ WHERE ... ] [LIMIT ... ]
228 HANDLER tbl_name CLOSE
229 
230 HANDLER 語句提供了直接訪問 MyISAM 表存儲引擎的介面。 
231 
232 HANDLER 語句的第一個形式打開一個表,通過後來的 HANDLER ... READ 語句使它可讀取。這個表對象將不能被其它線程共用,也不會被關閉,除非線程調用 HANDLER tbl_name CLOSE 或線程關閉。 
233 
234 第二個形式讀取指定的索引遵從那個條件並且適合 WHERE 條件的一行(或更多的,由 LIMIT 子句指定)。如果索引由幾個部分組成(範圍有幾個列),值以逗號分隔的列表指定;如果只提供的一部分值,那麼第一個列是必需的。 
235 
236 第三個形式從表中以索引的順序讀取匹配 WHERE 條件的一行(或更多的,由 LIMIT 子句指定)。 
237 
238 第四個形式(沒有索引清單)從表中以自然的列順序(在數據文件中存儲的次序)讀取匹配 WHERE 條件的一行(或更多的,由 LIMIT 子句指定)。如果期望做一個全表掃描,它將比 HANDLER tbl_name READ index_name 更快。 
239 
240 HANDLER ... CLOSE 關閉一個以 HANDLER ... OPEN 打開的表。 
241 
242 HANDLER 是一個稍微低級的語句。舉例來說,它不提供一致性約束。更確切地說,HANDLER ... OPEN 不 接受一個表的快照,並且 不 鎖定表。這就意味著在一個 HANDLER ... OPEN 被執行後,表數據仍會被 (這個或其它的線程) 修改,這些修改可能在 HANDLER ... NEXT 和 HANDLER ... PREV 掃描中才會部分地出現。 
243 
244 使用這個介面代替普通 SQL 的原因是: 
245 
246 它比 SELECT 快,因為: 
247 在 HANDLER OPEN 中,一個指定的存儲引擎被分配給當前線程。 
248 較少的複雜解析。 
249 沒有優化器和沒有查詢檢查開銷。 
250 在兩個處理請求之間不需要鎖定使用的表。 
251 介面處理機並不提供一個一致性的查看數據 (舉例來說,讀污染 dirty-reads 是允許的),因而,存儲引擎可以做 SQL 通常不允許的優化。 
252 它使得更加容易地移植一個使用對 MySQL 的 ISAM 類似介面的應用程式。 
253 它允許你在一個以 SQL 不容易完成(在某些不可能的完全)的情況下遍歷一個資料庫。當使用提供了一個互動式的用戶介面訪問資料庫的應用程式時,介面處理機是更加自然的查看數據的方式。 
254 6.4.3 INSERT 句法
255 
256     INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
257         [INTO] tbl_name [(col_name,...)]
258         VALUES ((expression | DEFAULT),...),(...),...
259         [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]
260 or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
261         [INTO] tbl_name [(col_name,...)]
262         SELECT ...
263 or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
264         [INTO] tbl_name
265         SET col_name=(expression | DEFAULT), ...
266         [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]
267 
268 
269 INSERT 將新行插入到一個已存在的表中。INSERT ... VALUES 形式的語句基於明確的值插入記錄行。INSERT ... SELECT 形式的語句從另一個或多個表中選取出值,並將其插入。有多重值列表的 INSERT ... VALUES 形式的語句在 MySQL 3.22.5 或更新的版本中被支持。col_name=expression 句法在 MySQL 3.22.10 或更新的版本中得到支持。 
270 
271 tbl_name 是記錄將要被插入的表。列名列表或 SET 子句指出語句指定的值賦給哪個列: 
272 
273 如果在 INSERT ... VALUES 或 INSERT ... SELECT 中沒有指定列列表,那麼所有列的值必須在 VALUES() 列表中或由 SELECT 提供。如果你不知道表的列的次序,可以使用 DESCRIBE tbl_name 來決定它。 
274 
275 任何沒有明確指定一個值的列均會被設置為它的預設值。舉例來說,如果你指定的一個列列表沒有指定表中所有的列,未指定的列將被設置為它們的預設值。預設值賦值的描述在章節 6.5.3 CREATE TABLE 句法。 你也可以使用關鍵詞 DEFAULT 來將一個列設置為它的預設值(這在 MySQL 4.0.3 中被新加入)。這使它更加容易地書寫賦予值到所有除了幾列的 INSERT 語句,因為它允許您避免書寫一個不完全的 VALUES() 的列表(在該列表沒有包含表中的每個列的列值)。否則,你將不得不在 VALUES() 列表中寫出列列表指定對應的值。 MySQL 通常都會為每個欄位設置一個預設值。這是某些強加在 MySQL 上的,在事務型表與非事務型表中均工作。 我們的觀點是在應用程式端檢查欄位的內容,而不是在資料庫伺服器端。 
276 
277 一個 expression 可以引用先前在值列表中設置的任何列。例如,你可以這樣: 
278 mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
279 
280 但是不能這樣: 
281 mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
282 
283 如果你指定關鍵詞 LOW_PRIORITY,INSERT 的執行將會被延遲,直到沒有其它客戶端正在讀取表。在這種情況下,客戶端不得不等待插入語句被完成,如果表被頻繁地使用,那麼這將會花費很長一段時間。這與 INSERT DELAYED 讓客戶端立即繼續執行正好相反。查看章節 6.4.4 INSERT DELAYED 句法。註意,LOW_PRIORITY 通常不對 MyISAM 使用,因為這將禁止併發的插入。查看章節 7.1 MyISAM 表。 
284 
285 如果你在一個有許多條記錄行值的 INSERT 中指定關鍵詞 IGNORE,任何在表中現有的 PRIMARY 或 UNIQUE 鍵上重覆的記錄行均會被忽略而不被插入。如果你不指定 IGNORE,當有任何記錄行在一個現有的鍵值上重覆時,插入均會被中止。你可以通過 C API 函數 mysql_info() 測定共有多少記錄行被插入到表中。 
286 
287 如果你指定 ON DUPLICATE KEY UPDATE 子句(在 MySQL 4.1.0 中被新加入),並且被插入的一個記錄行在 PRIMARY 或 UNIQUE 鍵上將會產生一個重覆值,那麼老的記錄行將被 UPDATE。舉例來說: 
288 mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
289    --> ON DUPLICATE KEY UPDATE c=c+1;
290 
291 假設列 a 被定義為 UNIQUE,並且已存在了一個 1,它將與下麵的語句產生同樣的結果: 
292 mysql> UPDATE table SET c=c+1 WHERE a=1;
293 
294 註意:如果列 b 也是唯一的,UPDATE 命令將要被寫成這樣: 
295 mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
296 
297 並且如果 a=1 OR b=2 匹配幾個記錄行,只有 一個 記錄行將被更新!大體上,在有多重 UNIQUE 鍵的表上,你應該儘是避免使用 ON DUPLICATE KEY 子句。 當使用了 ON DUPLICATE KEY UPDATE 後,DELAYED 選項將被忽略。 
298 
299 如果 MySQL 被設置為使用 DONT_USE_DEFAULT_FIELDS 選項,INSERT 語句將產生一個錯誤,除非你為所有需要一個非 NULL 值的列明確指定值。查看章節 2.3.3 典型的 configure 選項。 
300 
301 通過使用 mysql_insert_id 函數你可以找到用於一個 AUTO_INCREMENT 列的值。查看章節 8.1.3.130 mysql_insert_id()。 
302 如果你使用 INSERT ... SELECT 或一個 INSERT ... VALUES 語句插入多值列,你可以使用 C API 函數 mysql_info() 得到查詢的信息。信息字串的格式如下: 
303 
304 Records: 100 Duplicates: 0 Warnings: 0
305 
306 Duplicates 指出因與某些現有的唯一索引值重覆而不能被插入的記錄行數目。Warnings 指出在嘗試插入的列值中在某些方面可能有問題的數目。在下列任何一個條件下,警告都會發生: 
307 
308 向一個定義為 NOT NULL 的列中插入 NULL 值。該列被設置為它的預設值。 
309 將一個超出列範圍的值賦給一個數字列。該值被剪切到該範圍內的適當的端點。 
310 將一個例如 '10.34 a' 的值賦給一個數字列。尾部的無用信息將被剝離,保留數字部分並將其插入。如果該值看起來根本就不是一個數字,該列將被設置為 0。 
311 將一個超出了列最大長度的字元串插入到一個 CHAR、VARCHAR、TEXT 或 BLOB 列中。該值將被剪切到該列的最大長度。 
312 將一個對列類型不合法的值插入到一個日期或時間列中。該列被適當格式的零值。 
313 
314 6.4.3.1 INSERT ... SELECT 句法
315 INSERT [LOW_PRIORITY] [IGNORE] [INTO] tbl_name [(column list)] SELECT ...
316 
317 使用 INSERT ... SELECT 語句,你可以從一個或多個表中讀取多個記錄行,並將其快速地插入到一個表中。 
318 
319 INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE
320 tblTemp1.fldOrder_ID > 100;
321 
322 一個 INSERT ... SELECT 語句有下列條件的限止: 
323 
324 INSERT 語句中的目標表不能在 SELECT 查詢部分的 FROM 子句中出現,因為在 ANSI SQL 中,禁止你從正在插入的表中 SELECT。(問題是因為,SELECT 可能會發現在同一運行期內先前被插入的記錄。當使用子選擇子句時,這種情況將會更容易混淆!) 
325 AUTO_INCREMENT 列像平常一樣工作。 
326 你可以使用 C API 函數 mysql_info() 得到查詢的信息。查看章節 6.4.3 INSERT 句法。 
327 為了確保二進位日誌可以被用於重建最初的表,MySQL 將不允許在 INSERT ... SELECT 期間併發的插入。 
328 你當然也可以使用 REPLACE 代替 INSERT 來蓋寫老的記錄行。 
329 
330 6.4.4 INSERT DELAYED 句法
331 
332 
333 INSERT DELAYED ...
334 
335 INSERT 語句的 DELAYED 選項是一個 MySQL 特有的選項,如果你的客戶端不能等待 INSERT 的完成,這將會是很有用的。This is a common problem when you use MySQL for logging and 當你打開日誌記錄使用 MySQL 並且你周期性的需花費很長時間才完成的 SELECT 和 UPDATE 語句時,這將是一個很普遍的問題。DELAYED 在 MySQL 3.22.15 中被引入。它是 MySQL 對 ANSI SQL92 的一個擴展。 
336 
337 INSERT DELAYED 僅僅工作與 ISAM 和 MyISAM 表。註意,因為 MyISAM 表支持併發的 SELECT 和 INSERT,如果在數據文件中沒有空閑的塊,那你將很少需要對 MyISAM 表使用 INSERT DELAYED。查看章節 7.1 MyISAM 表。 
338 
339 當你使用 INSERT DELAYED 時,客戶端將立即得到一個 OK,當表不被任何其它線程使用時,該行將被插入。 
340 
341 使用 INSERT DELAYED 的另一個主要的好處就是,從很多客戶端來的插入請求會被打包在一起並寫入一個塊中。這比做許多單獨的插入要快的多。 
342 
343 註意,當前的記錄行隊列是被存儲在記憶體中的,一直到他們被插入到表中。這就意味著,如果你使用強制的方法(kill -9) 殺死 mysqld,或者如果意外地死掉,任何沒有寫到磁碟中的記錄行隊列都將會丟失! 
344 
345 下麵詳細地描述當你為 INSERT 或 REPLACE 使用 DELAYED 選項時會發生什麼。在這個描述中,“線程”是遇到一個 INSERT DELAYED 命令的線程,“處理器”是處理所有對於一個特定表的 INSERT DELAYED 語句的線程。 
346 
347 當一個線程對一個表執行一個 DELAYED 語句時,將會創建一個處理器線程用以處理對該表的所有 DELAYED 語句,除非這樣的處理器已經存在。 
348 
349 線程檢查處理器是否已經獲得了一個 DELAYED 鎖;如果還沒有,這告訴處理程式去獲得。即使其它的線程已在表上加了一個 READ 或 WRITE 鎖,也能獲得 DELAYED 鎖。然而,處理器將等待所有的 ALTER TABLE 鎖或 FLUSH TABLES 以保證表結構是最新的。 
350 
351 線程執行 INSERT 語句,但是並不將記錄行寫到表中,它將最終的記錄行的副本放到被處理器線程管理的隊列中。任何語法錯誤都會被線程發現並報告給客戶程式。 
352 
353 客戶端不能報告結果記錄行中重覆次數或 AUTO_INCREMENT 值;它不能從伺服器獲

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 執行資料庫查詢時,有完整查詢和模糊查詢之分。 一般模糊語句格式如下: SELECT 欄位 FROM 表 WHERE 某欄位 LIKE 條件 其中關於條件,SQL提供了四種匹配模式: 1、% :表示任意0個或多個字元。可匹配任意類型和長度的字元,有些情況下若是中文,請使用兩個百分號(%%)表示。 例如 ...
  • 1、選取最適用的欄位屬性 MySQL可以很好的支持大數據量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中欄位的寬度設得儘可能小。 例如,在定義郵政編碼這個欄位時,如果將其設置為CHAR(255),顯然給資料庫增加了不必要 ...
  • 啟動該隨筆的原因,個人因為辭職較多空檔期,故本著重新學習的動力以及為了記錄自己學習 開始學習一些概念性的東西吧(PS:博主,PHP開發 一枚) Data 數據 :經過語義解釋的值 Database(DB) 資料庫 :數據的倉庫 Database Management System(DBMS) 資料庫 ...
  • 布爾查詢是最常用的組合查詢,不僅將多個查詢條件組合在一起,並且將查詢的結果和結果的評分組合在一起。當查詢條件是多個表達式的組合時,布爾查詢非常有用,實際上,布爾查詢把多個子查詢組合(combine)成一個布爾表達式,所有子查詢之間的邏輯關係是與(and);只有當一個文檔滿足布爾查詢中的所有子查詢條件... ...
  • 使用Sqoop遠程連接MySQL導入數據到HBase資料庫: 出現了拒絕連接的錯誤: 把主機名換成IP地址就正常了。 ...
  • 基本思路就是為mysql.user表增加一條記錄:'hadoop'@'%',這樣,任何主機上的用戶'hadoop'都可以遠程連接MySQL資料庫。於是輸入下麵的命令: 結果出現了錯誤: 這是因為指定了嚴格模式,不能直接往mysql.user表裡面insert用戶: 只能輸入下麵兩個命令來實現: 這樣 ...
  • MySQL — 連接器 連接器的概念 它們往往是一類Python包,或者是一類已經寫好的Python庫。這些庫提供了我們Python去連接資料庫伺服器的基本功能。 ​ 既然它是一個包,那麼我們首先學會導入這個包 #! /usr/bin/env python3 # coding: utf-8 ​ fr ...
  • 數據定義: CREATE、DROP、ALTER ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...