国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

MySQL 4.1.0 中文參考手冊 --- 6.4 數(shù)據(jù)操縱:select, insert, UP

2024-07-24 12:54:50
字體:
供稿:網(wǎng)友
菜鳥學堂:
mysql 4.1.0 中文參考手冊 --- 犬犬(心帆)翻譯 mysql reference manual for version 4.1.0-alpha.

6.4 數(shù)據(jù)操縱:select, insert, update, delete6.4.1 select 句法


select [straight_join] [sql_small_result] [sql_big_result] [sql_buffer_result] [sql_cache | sql_no_cache] [sql_calc_found_rows] [high_priority] [distinct | distinctrow | all] select_expression,... [into {outfile | dumpfile} 'file_name' export_options] [from table_references [where where_definition] [group by {unsigned_integer | col_name | formula} [asc | desc], ...] [having where_definition] [order by {unsigned_integer | col_name | formula} [asc | desc] ,...] [limit [offset,] rows | rows offset offset] [procedure procedure_name(argument_list)] [for update | lock in share mode]]

select 用于檢索從一個或多個表中選取出的行。select_expression 表示你希望檢索的列。select 也可以被用于檢索沒有引用任何表的計算列。例如:

mysql> select 1 + 1; -> 2

所有使用的關鍵詞必須嚴格以上面所顯示的次序被給出。舉例來說,一個 having 子句必須出現(xiàn)在 group by 子句后,在 order by 字句之前。
一個 select 表達式可以使用 as 指定一個別名。別名可以當作表達式的列名,用于 order by 或 having 子句中。例如:
mysql> select concat(last_name,', ',first_name) as full_name from mytable order by full_name;
在一個 where 子句中使用一個列別名是不允許的,因為,當 where 子句被執(zhí)行時,列值可能還沒有被計算確定。查看章節(jié) a.5.4 使用 alias 的限制。

from table_references 子句表示從哪個表中檢索記錄行。如果你命名超過超過一個表,并執(zhí)行一個 join。對于 join 句法的信息,查看章節(jié) 6.4.1.1 join 句法。對于每個引用的表,你可以順便指定一個別名。
table_name [[as] alias] [[use index (key_list)] | [ignore index (key_list)] | force index (key_list)]]
到 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 的同義詞。

你可以以 tbl_name (在當前的數(shù)據(jù)庫中) 引用一張表,或以 dbname.tbl_name 明確地指定其個數(shù)據(jù)。你要以以 col_name、tbl_name.col_name 或 db_name.tbl_name.col_name 引用一個列。 你不需要在一個 select 語句中引用的列前指定 tbl_name 或 db_name.tbl_name 前綴,除非引用列存在二義性。查看章節(jié) 6.1.2 數(shù)據(jù)庫、表、索引、列和別名,對于有歧義的列引用需要更加顯式的列引用格式。

一個表的引用可以使用 tbl_name [as] alias_name 給以別名:
mysql> select t1.name, t2.salary from employee as t1, info as t2 -> where t1.name = t2.name;mysql> select t1.name, t2.salary from employee t1, info t2 -> where t1.name = t2.name;
選取出來用于輸出的列可以在 order by 和 group by 子句中使用列名、列的別名或列的位置來引用。列的位置從 1 開始:
mysql> select college, region, seed from tournament -> order by region, seed;mysql> select college, region as r, seed as s from tournament -> order by r, s;mysql> select college, region, seed from tournament -> order by 2, 3;
為了以倒序排序,可以在 order by 子句中用于排序的列名后添加一個 desc (遞減 descending)關鍵詞。缺省為升序排序;這也可以通過使用 asc 關鍵詞明確指定。

在 where 子句中可以使用 mysql 支持的任何函數(shù)。查看章節(jié) 6.3 用于 select 和 where 子句的函數(shù)。

having 子句可以引用任何列或在 select_expression 中命名的別名。它在最后被執(zhí)行,僅僅就在項目被送到客戶端之前,不進行任何優(yōu)化。所以不要對應該放在 where 子句中的項目使用 having。舉例來說,不要寫成這樣:
mysql> select col_name from tbl_name having col_name > 0;
用這個代替:
mysql> select col_name from tbl_name where col_name > 0;
在 mysql 3.22.5 或以后的版本中,你也可以這下面的形式書寫一個查詢:
mysql> select user,max(salary) from users -> group by user having max(salary)>10;
在較早的 mysql 版本中,你可能需要用下面的代替了:
mysql> select user,max(salary) as sum from users -> group by user having sum>10;
distinct、distinctrow 和 all 選項指定重復的記錄行是否被返回。缺省為 (all),返回所有匹配的記錄行。distinct 和 distinctrow 是同義詞,它指定結(jié)果集重復的記錄行被排除。

所有以 sql_ 開頭、straight_join 和 high_priority 的選項是 mysql 對 ansi sql 的擴展。

high_priority 將給 select 語句比更新一個表有更高的優(yōu)先級。你只應該對非常快的或需要立即返回的查詢使用它。 如果一個表已被讀鎖定,甚至是有一個更新語句正在等待表的釋放,一個 select high_priority 查詢也將會執(zhí)行。

sql_big_result 可以與 group by 或 distinct 一同使用,以告訴優(yōu)化器結(jié)果集將有許多記錄行。在這種情況下,如果需要,mysql 將直接使用基于磁盤的臨時表。同樣的,在這種情況下,mysql 更愿意以 group by 上的一個鍵進行排序而不是建立一個臨時表。

sql_buffer_result 將強制把結(jié)果放入一個臨時表。這將有助于 mysql 盡早地釋放表和有助于將大的結(jié)果集傳送到客戶端。

sql_small_result, 一個 mysql 特有的選項,可以與 group by 或 distinct 一同使用,以告訴優(yōu)化器結(jié)果集將會很小。在這種情況下,mysql 將使用快速的臨時表存儲結(jié)果表,而不是使用排序。在 mysql 3.23 中,這通常是不需要的。

sql_calc_found_rows (版本 4.0.0 和更新的) 告訴 mysql 計算在不考慮 limit 子句時結(jié)果集中將有多少行記錄。然后使用 select found_rows() 可以檢索到記錄行的數(shù)目。查看章節(jié) 6.3.6.2 輔助功能函數(shù)。請注意,在早于 4.1.0 的版本中,limit 0 是不工作的,它將被優(yōu)化為立即返回(結(jié)果集的記錄數(shù)為 0)。查看章節(jié) 5.2.8 mysql 如何優(yōu)化 limit。

如果你使用了 query_cache_type=2 (demand),sql_cache 告訴 mysql 將存儲查詢結(jié)果放入查詢高速緩存內(nèi)。查看章節(jié) 6.9 mysql 的查詢高速緩存。

sql_no_cache 告訴 mysql 不允許將查詢結(jié)果存儲到查詢緩存內(nèi)。查看章節(jié) 6.9 mysql 的查詢高速緩存。

如果使用了 group by,輸出記錄將會依照 group by 列進行排序,就好像你對所有 group by 中的所有字段使用了 order by。mysql 擴展了 group by 的用法,所以你也可以在 group by 中指定 asc 和 desc:
select a,count(b) from test_table group by a desc
mysql 擴展了的 group by 用法允許你選取沒有在 group by 子句中提及的字段。如果你的查詢沒有得到你所期望的結(jié)果,請查看 group by 中的描述。查看章節(jié) 6.3.7 用于 group by 子句的函數(shù)。

straight_join 強制優(yōu)化器以表在 from 子句中列出的順序聯(lián)結(jié)。如果優(yōu)化器以一個非優(yōu)化的次序聯(lián)結(jié)各表,你可以使用它來加速一個查詢。查看章節(jié) 5.2.1 explain 句法(得到有關 select 的信息)。

limit 子句可以被用于強制 select 語句返回指定的記錄數(shù)。limit 接受一個或兩個數(shù)字參數(shù)。參數(shù)必須是一個整數(shù)常量。如果給定兩個參數(shù),第一個參數(shù)指定第一個返回記錄行的偏移量,第二個參數(shù)指定返回記錄行的最大數(shù)目。初始記錄行的偏移量是 0(而不是 1):為了與 postgresql 兼容,mysql 也支持句法:limit # offset #。
mysql> select * from table limit 5,10; # 檢索記錄行 6-15
為了檢索從某一個偏移量到記錄集的結(jié)束所有的記錄行,可以指定第二個參數(shù)為 -1:
mysql> select * from table limit 95,-1; # 檢索記錄行 96-last.
如果只給定一個參數(shù),它表示返回最大的記錄行數(shù)目:
mysql> select * from table limit 5; # 檢索前 5 個記錄行
換句話說,limit n 等價于 limit 0,n。

select ... into outfile 'file_name' 格式的 select 將選擇的記錄行寫入一個文件。文件被建立在服務器主機上,并且不可以是已存在的 (不管別的,這可以防止數(shù)據(jù)庫表和文件例如 `/etc/passwd' 被破壞)。你必須在服務器主機上有 file 權(quán)限來使用這個形式的 select。select ... into outfile 主要是有意于讓你能夠在服務主機上快速地轉(zhuǎn)儲一個表。如果你希望將結(jié)果文件建立在其它的主機上,而不是服務器上,你就不能使用 select ... into outfile。在這種情況下,你應該使用某些客戶端程序例如 mysqldump --tab 或 mysql -e "select ..." > outfile 產(chǎn)生文件來代替它。select ... into outfile 是 load data infile 的逆操作;語句中的 export_options 部分的句法由 fields 和 lines 子句組成,它們與與用在 load data infile 語句中的相同。查看章節(jié) 6.4.9 load data infile 句法。在結(jié)果文本文件中,只有下列的字符被 escaped by 指定的字符轉(zhuǎn)義:escaped by 字符在 fields terminated by 中的第一個字符在 lines terminated by 中的第一個字符另外,ascii 0 被轉(zhuǎn)換到 escaped by 后而跟一個 0 (ascii 48)。上述行為的原因是,你必須 轉(zhuǎn)義任何 fields terminated by、escaped by 或lines terminated by 字符,以便能可靠地將文件讀回。ascii 0 被轉(zhuǎn)義是為了更容易地使用某些分頁程序查看它。因為結(jié)果文件并不需要遵從 sql 句法,所以其它是不需要轉(zhuǎn)義。下面的例子得到的文件是可用于許多老程序的格式。
select a,b,a+b into outfile "/tmp/result.text"fields terminated by ',' optionally enclosed by '"'lines terminated by "/n"from test_table;
如果使用 into dumpfile 代替 into outfile,mysql 將在文件中只寫一行,沒任何列或行端接和任何轉(zhuǎn)義。如果你希望存儲一個 blob 列到文件中,這是非常有用的。注意,任何由 into outfile 和 into dumpfile 創(chuàng)建的文件將被所有用戶可讀寫!原因是,mysql 服務器不能夠創(chuàng)建一個其他用戶擁有的文件,(你決不應該以 root 身份運行 mysqld),該文件必須是公共可讀寫的,以便于你能操作它。

如果你以頁/行鎖使用在一個存儲引擎上 for update,被檢索的記錄行將被寫鎖。6.4.1.1 join 句法


mysql 支持在 select 中使用下面所示的 join 句法:

table_reference, table_referencetable_reference [cross] join table_referencetable_reference inner join table_reference join_conditiontable_reference straight_join table_referencetable_reference left [outer] join table_reference join_conditiontable_reference left [outer] join table_referencetable_reference natural [left [outer]] join table_reference{ oj table_reference left outer join table_reference on conditional_expr }table_reference right [outer] join table_reference join_conditiontable_reference right [outer] join table_referencetable_reference natural [right [outer]] join table_reference

table_reference 定義如下:

table_name [[as] alias] [[use index (key_list)] | [ignore index (key_list)] | [force index (key_list)]]

join_condition 定義如下:

on conditional_expr |using (column_list)

通常不應該在 on 存在任何條件式,它是用于限制在結(jié)果集中有哪個行的(對于這個規(guī)則也有例外)。如果你希望哪個記錄行應該在結(jié)果中,你必須在 where 子句中限制它。

注意,在早于 3.23.17 的版本中,inner join 不接受一個 join_condition!

上面所顯示的最后一個 left outer join 句法僅僅是為了與 odbc 兼容而存在的:
一個表引用可以使用 tbl_name as alias_name 或 tbl_name alias_name 命以別名:
mysql> select t1.name, t2.salary from employee as t1, info as t2 -> where t1.name = t2.name;
on 條件是可以用在一個 where 子句中的任何形式的條件。

如果在一個 left join 的 on 或 using 部分中右表沒有匹配的記錄,一個所有列被設置為 null 的記錄行將被用于右表。你可以通過這個行為找到一個表在另一個表中沒有配對物的記錄:
mysql> select table1.* from table1 -> left join table2 on table1.id=table2.id -> where table2.id is null;
這個例子在 table1 中找到所有的記錄行,其 id 值沒有出現(xiàn)在 table2 中(即,所有在 table1 存在的,但在 table2 中沒有對應記錄的記錄行)。當然,這是假定 table2.id 被聲明為 not null 的。查看章節(jié) 5.2.6 mysql 如何優(yōu)化 left join 和 right join。

using (column_list) 子句指定了一個列的列表,列表的中列必須同時存在于兩個表中。例如 using 子句如下所示:
a left join b using (c1,c2,c3,...)
它可以被定義為在語義上等同于一個這樣的 on 表達式:
a.c1=b.c1 and a.c2=b.c2 and a.c3=b.c3,...
兩個表的 natural [left] join 被定義為在語義上等同于使用了 using 子句指定存在于兩張表中的所有列的一個 inner join 或一個 left join。

inner join 和 , (逗號) 在語義上是等同的。都是在所有的表之間進行一個全聯(lián)結(jié)。通常,在 where 條件中指定表應該如何聯(lián)結(jié)。

right join 作用類似于 left join。為了保持數(shù)據(jù)庫邊的代碼上精簡,left join 被推薦使用來代替 right join。

straight_join 等同于 join,除了左表先于右表被讀入。當聯(lián)結(jié)優(yōu)化器將表的順序放錯時(很少),這可用于這種情況。

到 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 的同義詞。
一些例子:

mysql> select * from table1,table2 where table1.id=table2.id;mysql> select * from table1 left join table2 on table1.id=table2.id;mysql> select * from table1 left join table2 using (id);mysql> select * from table1 left join table2 on table1.id=table2.id -> left join table3 on table2.id=table3.id;mysql> select * from table1 use index (key1,key2) -> where key1=1 and key2=2 and key3=3;mysql> select * from table1 ignore index (key3) -> where key1=1 and key2=2 and key3=3;

查看章節(jié) 5.2.6 mysql 如何優(yōu)化 left join 和 right join。
6.4.1.2 union 句法


select ...union [all]select ... [union select ...]

union 在 mysql 4.0.0 中被實現(xiàn)。

union 用于將多個 select 語句的結(jié)果聯(lián)合到一個結(jié)果集中。

在 select 中的 select_expression 部分列出的列必須具有同樣的類型。第一個 select 查詢中使用的列名將作為結(jié)果集的列名返回。

select 命令是一個普通的選擇命令,但是有下列的限制:
只有最后一個 select 命令可以有 into outfile。
如果你不為 union 使用關鍵詞 all,所有返回的記錄行將是唯一的,就好像你為整個返回集使用了一個 distinct。如果你指定了 all,那么你將得到從所有使用的 select 語句中返回的所有匹配記錄行。

如果你希望對整個 union 結(jié)果使用一個 order by,你應該使用圓括號:

(select a from table_name where a=10 and b=1 order by a limit 10)union(select a from table_name where a=11 and b=2 order by a limit 10)order by a;

6.4.2 handler 句法
handler tbl_name open [ as alias ]handler tbl_name read index_name { = | >= | <= | < } (value1,value2,...) [ where ... ] [limit ... ]handler tbl_name read index_name { first | next | prev | last } [ where ... ] [limit ... ]handler tbl_name read { first | next } [ where ... ] [limit ... ]handler tbl_name close

handler 語句提供了直接訪問 myisam 表存儲引擎的接口。

handler 語句的第一個形式打開一個表,通過后來的 handler ... read 語句使它可讀取。這個表對象將不能被其它線程共享,也不會被關閉,除非線程調(diào)用 handler tbl_name close 或線程關閉。

第二個形式讀取指定的索引遵從那個條件并且適合 where 條件的一行(或更多的,由 limit 子句指定)。如果索引由幾個部分組成(范圍有幾個列),值以逗號分隔的列表指定;如果只提供的一部分值,那么第一個列是必需的。

第三個形式從表中以索引的順序讀取匹配 where 條件的一行(或更多的,由 limit 子句指定)。

第四個形式(沒有索引清單)從表中以自然的列順序(在數(shù)據(jù)文件中存儲的次序)讀取匹配 where 條件的一行(或更多的,由 limit 子句指定)。如果期望做一個全表掃描,它將比 handler tbl_name read index_name 更快。

handler ... close 關閉一個以 handler ... open 打開的表。

handler 是一個稍微低級的語句。舉例來說,它不提供一致性約束。更確切地說,handler ... open 不 接受一個表的快照,并且 不 鎖定表。這就意味著在一個 handler ... open 被執(zhí)行后,表數(shù)據(jù)仍會被 (這個或其它的線程) 修改,這些修改可能在 handler ... next 和 handler ... prev 掃描中才會部分地出現(xiàn)。

使用這個接口代替普通 sql 的原因是:
它比 select 快,因為:在 handler open 中,一個指定的存儲引擎被分配給當前線程。較少的復雜解析。沒有優(yōu)化器和沒有查詢檢查開銷。在兩個處理請求之間不需要鎖定使用的表。接口處理機并不提供一個一致性的查看數(shù)據(jù) (舉例來說,讀污染 dirty-reads 是允許的),因而,存儲引擎可以做 sql 通常不允許的優(yōu)化。它使得更加容易地移植一個使用對 mysql 的 isam 類似接口的應用程序。它允許你在一個以 sql 不容易完成(在某些不可能的完全)的情況下遍歷一個數(shù)據(jù)庫。當使用提供了一個交互式的用戶接口訪問數(shù)據(jù)庫的應用程序時,接口處理機是更加自然的查看數(shù)據(jù)的方式。6.4.3 insert 句法


insert [low_priority | delayed] [ignore] [into] tbl_name [(col_name,...)] values ((expression | default),...),(...),... [ on duplicate key update col_name=expression, ... ]or insert [low_priority | delayed] [ignore] [into] tbl_name [(col_name,...)] select ...or insert [low_priority | delayed] [ignore] [into] tbl_name set col_name=(expression | default), ... [ on duplicate key update col_name=expression, ... ]

insert 將新行插入到一個已存在的表中。insert ... values 形式的語句基于明確的值插入記錄行。insert ... select 形式的語句從另一個或多個表中選取出值,并將其插入。有多重值列表的 insert ... values 形式的語句在 mysql 3.22.5 或更新的版本中被支持。col_name=expression 句法在 mysql 3.22.10 或更新的版本中得到支持。

tbl_name 是記錄將要被插入的表。列名列表或 set 子句指出語句指定的值賦給哪個列:
如果在 insert ... values 或 insert ... select 中沒有指定列列表,那么所有列的值必須在 values() 列表中或由 select 提供。如果你不知道表的列的次序,可以使用 describe tbl_name 來決定它。

任何沒有明確指定一個值的列均會被設置為它的缺省值。舉例來說,如果你指定的一個列列表沒有指定表中所有的列,未指定的列將被設置為它們的缺省值。缺省值賦值的描述在章節(jié) 6.5.3 create table 句法。你也可以使用關鍵詞 default 來將一個列設置為它的默認值(這在 mysql 4.0.3 中被新加入)。這使它更加容易地書寫賦予值到所有除了幾列的 insert 語句,因為它允許您避免書寫一個不完全的 values() 的列表(在該列表沒有包含表中的每個列的列值)。否則,你將不得不在 values() 列表中寫出列列表指定對應的值。mysql 通常都會為每個字段設置一個缺省值。這是某些強加在 mysql 上的,在事務型表與非事務型表中均工作。我們的觀點是在應用程序端檢查字段的內(nèi)容,而不是在數(shù)據(jù)庫服務器端。

一個 expression 可以引用先前在值列表中設置的任何列。例如,你可以這樣:
mysql> insert into tbl_name (col1,col2) values(15,col1*2);
但是不能這樣:
mysql> insert into tbl_name (col1,col2) values(col2*2,15);
如果你指定關鍵詞 low_priority,insert 的執(zhí)行將會被延遲,直到?jīng)]有其它客戶端正在讀取表。在這種情況下,客戶端不得不等待插入語句被完成,如果表被頻繁地使用,那么這將會花費很長一段時間。這與 insert delayed 讓客戶端立即繼續(xù)執(zhí)行正好相反。查看章節(jié) 6.4.4 insert delayed 句法。注意,low_priority 通常不對 myisam 使用,因為這將禁止并發(fā)的插入。查看章節(jié) 7.1 myisam 表。

如果你在一個有許多條記錄行值的 insert 中指定關鍵詞 ignore,任何在表中現(xiàn)有的 primary 或 unique 鍵上重復的記錄行均會被忽略而不被插入。如果你不指定 ignore,當有任何記錄行在一個現(xiàn)有的鍵值上重復時,插入均會被中止。你可以通過 c api 函數(shù) mysql_info() 測定共有多少記錄行被插入到表中。

如果你指定 on duplicate key update 子句(在 mysql 4.1.0 中被新加入),并且被插入的一個記錄行在 primary 或 unique 鍵上將會產(chǎn)生一個重復值,那么老的記錄行將被 update。舉例來說:
mysql> insert into table (a,b,c) values (1,2,3) --> on duplicate key update c=c+1;
假設列 a 被定義為 unique,并且已存在了一個 1,它將與下面的語句產(chǎn)生同樣的結(jié)果:
mysql> update table set c=c+1 where a=1;
注意:如果列 b 也是唯一的,update 命令將要被寫成這樣:
mysql> update table set c=c+1 where a=1 or b=2 limit 1;
并且如果 a=1 or b=2 匹配幾個記錄行,只有 一個 記錄行將被更新!大體上,在有多重 unique 鍵的表上,你應該盡是避免使用 on duplicate key 子句。當使用了 on duplicate key update 后,delayed 選項將被忽略。

如果 mysql 被設置為使用 dont_use_default_fields 選項,insert 語句將產(chǎn)生一個錯誤,除非你為所有需要一個非 null 值的列明確指定值。查看章節(jié) 2.3.3 典型的 configure 選項。

通過使用 mysql_insert_id 函數(shù)你可以找到用于一個 auto_increment 列的值。查看章節(jié) 8.1.3.130 mysql_insert_id()。
如果你使用 insert ... select 或一個 insert ... values 語句插入多值列,你可以使用 c api 函數(shù) mysql_info() 得到查詢的信息。信息字串的格式如下:

records: 100 duplicates: 0 warnings: 0

duplicates 指出因與某些現(xiàn)有的唯一索引值重復而不能被插入的記錄行數(shù)目。warnings 指出在嘗試插入的列值中在某些方面可能有問題的數(shù)目。在下列任何一個條件下,警告都會發(fā)生:
向一個定義為 not null 的列中插入 null 值。該列被設置為它的缺省值。將一個超出列范圍的值賦給一個數(shù)字列。該值被剪切到該范圍內(nèi)的適當?shù)亩它c。將一個例如 '10.34 a' 的值賦給一個數(shù)字列。尾部的無用信息將被剝離,保留數(shù)字部分并將其插入。如果該值看起來根本就不是一個數(shù)字,該列將被設置為 0。將一個超出了列最大長度的字符串插入到一個 char、varchar、text 或 blob 列中。該值將被剪切到該列的最大長度。將一個對列類型不合法的值插入到一個日期或時間列中。該列被適當格式的零值。

6.4.3.1 insert ... select 句法
insert [low_priority] [ignore] [into] tbl_name [(column list)] select ...

使用 insert ... select 語句,你可以從一個或多個表中讀取多個記錄行,并將其快速地插入到一個表中。

insert into tbltemp2 (fldid) select tbltemp1.fldorder_id from tbltemp1 wheretbltemp1.fldorder_id > 100;

一個 insert ... select 語句有下列條件的限止:
insert 語句中的目標表不能在 select 查詢部分的 from 子句中出現(xiàn),因為在 ansi sql 中,禁止你從正在插入的表中 select。(問題是因為,select 可能會發(fā)現(xiàn)在同一運行期內(nèi)先前被插入的記錄。當使用子選擇子句時,這種情況將會更容易混淆!)auto_increment 列像平常一樣工作。你可以使用 c api 函數(shù) mysql_info() 得到查詢的信息。查看章節(jié) 6.4.3 insert 句法。為了確保二進制日志可以被用于重建最初的表,mysql 將不允許在 insert ... select 期間并發(fā)的插入。
你當然也可以使用 replace 代替 insert 來蓋寫老的記錄行。
6.4.4 insert delayed 句法




insert delayed ...

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 的一個擴展。

insert delayed 僅僅工作與 isam 和 myisam 表。注意,因為 myisam 表支持并發(fā)的 select 和 insert,如果在數(shù)據(jù)文件中沒有空閑的塊,那你將很少需要對 myisam 表使用 insert delayed。查看章節(jié) 7.1 myisam 表。

當你使用 insert delayed 時,客戶端將立即得到一個 ok,當表不被任何其它線程使用時,該行將被插入。

使用 insert delayed 的另一個主要的好處就是,從很多客戶端來的插入請求會被打包在一起并寫入一個塊中。這比做許多單獨的插入要快的多。

注意,當前的記錄行隊列是被存儲在內(nèi)存中的,一直到他們被插入到表中。這就意味著,如果你使用強制的方法(kill -9) 殺死 mysqld,或者如果意外地死掉,任何沒有寫到磁盤中的記錄行隊列都將會丟失!

下面詳細地描述當你為 insert 或 replace 使用 delayed 選項時會發(fā)生什么。在這個描述中,“線程”是遇到一個 insert delayed 命令的線程,“處理器”是處理所有對于一個特定表的 insert delayed 語句的線程。
當一個線程對一個表執(zhí)行一個 delayed 語句時,將會創(chuàng)建一個處理器線程用以處理對該表的所有 delayed 語句,除非這樣的處理器已經(jīng)存在。

線程檢查處理器是否已經(jīng)獲得了一個 delayed 鎖;如果還沒有,這告訴處理程序去獲得。即使其它的線程已在表上加了一個 read 或 write 鎖,也能獲得 delayed 鎖。然而,處理器將等待所有的 alter table 鎖或 flush tables 以保證表結(jié)構(gòu)是最新的。

線程執(zhí)行 insert 語句,但是并不將記錄行寫到表中,它將最終的記錄行的副本放到被處理器線程管理的隊列中。任何語法錯誤都會被線程發(fā)現(xiàn)并報告給客戶程序。

客戶端不能報告結(jié)果記錄行中重復次數(shù)或 auto_increment 值;它不能從服務器獲得它們,因為 insert 早在插入操作被完成之前就返回了。如果你使用 c api,mysql_info() 函數(shù)也因同樣的原因而不能獲得任何有意義的信息。

當記錄行被插入到表中時,二進制的日志文件將被處理器線程更新。對于多記錄行的插入,當?shù)谝粋€記錄行被插入時,二進制日志被更新。

當每寫入 delayed_insert_limit 個記錄行后,處理器檢查是否仍有任何 select 語句沒有解決。如果是這樣,處理器允許在繼續(xù)之前讓這些語句先執(zhí)行。

當處理器發(fā)現(xiàn)在它的隊列中沒有太多的記錄行時,表將被解鎖。如果在 delayed_insert_timeout 秒內(nèi)沒有接收到新的 insert delayed 命令,處理器線程將終止。

如果在一個特定的處理器隊列中已有超過 delayed_queue_size 個記錄行未被解決,線程要求 insert delayed 等待,只到在隊列中有可用空間。這樣做是為了保證 mysqld 服務器對延遲內(nèi)存隊列不使用全部的內(nèi)存。

處理器線程在 mysql 進程列表中的 command 列上顯示為 delayed_insert。如果執(zhí)行一個 flush tables 命令或以 kill thread_id 殺死它,它將會被殺死。然而,它在退出前會首先將所隊列記錄行保存到表中。這些期間,它將不再接收其它線程的任何新的 insert 命令。如果再此之后執(zhí)行一個 insertdelayed 命令,一個新處理器線程將會被創(chuàng)建。注意,上面的意思是,如果一個 insert delayed 處理器已在運行,那么 insert delayed 命令將有比正常 insert 命令更高的優(yōu)先級!其它的更新命令將不得不等到 insert delayed 隊列被清空,殺死處理器線程(以 kill thread_id) 或執(zhí)行 flush tables。

下列狀態(tài)變量提供了有關 insert delayed 命令的信息:變量 含義 delayed_insert_threads 處理器線程數(shù)目delayed_writes 使用 insert delayed 寫入的記錄行的數(shù)目not_flushed_delayed_rows 等待被寫入的記錄行數(shù)目通過發(fā)出一個 show status 語句或通過執(zhí)行一個 mysqladmin extended-status 命令,你可以查看這些變量。
注意,如果表沒有在使用中,insert delayed 將比一個正常的 insert 慢。讓服務器為你使用 insert delayed 的每張表處理一個單獨的線程,也是有額外的開銷的。這就意味著,你應該在確定你的確需要它時才使用 insert delayed。
6.4.5 update 句法


update [low_priority] [ignore] tbl_name set col_name1=expr1 [, col_name2=expr2 ...] [where where_definition] [order by ...] [limit rows]orupdate [low_priority] [ignore] tbl_name [, tbl_name ...] set col_name1=expr1 [, col_name2=expr2 ...] [where where_definition]

update 以新的值更新現(xiàn)存表中行的列。set 子句指出要修改哪個列和他們應該給定的值。where 子句如果被給出,指定哪個記錄行應該被更新。否則,所有的記錄行被更新。如果 order by 子句被指定,記錄行將被以指定的次序更新。

如果你指定關鍵詞 low_priority,update 的執(zhí)行將被延遲,直到?jīng)]有其它的客戶端正在讀取表。

如果你指定關鍵詞 ignore,該更新語句將不會異常中止,即使在更新過程中出現(xiàn)重復鍵錯誤。導致沖突的記錄行將不會被更新。

如果在一個表達式中從 tbl_name 中訪問一個列,update 使用列的當前值。舉例來說,下面的語句設置 age 列值為它的當前值加 1 :

mysql> update persondata set age=age+1;

update 賦值是從左到右計算的。舉例來說,下列語句將 age 列設置為它的兩倍,然后再加 1 :

mysql> update persondata set age=age*2, age=age+1;

如果你設置列為其當前的值,mysql 注意到這點,并不更新它。

update 返回實際被改變的記錄行數(shù)目。在 mysql 3.22 或更新的版本中,c api 函數(shù) mysql_info()返回被匹配并更新的記錄行數(shù)目,以及在 update 期間發(fā)生的警告的數(shù)目。

在 mysql 3.23 中,你可以使用 limit # 來確保只有給定的記錄行數(shù)目被更改。

如果一個 order by 子句被使用(從 mysql 4.0.0 開始支持),記錄行將以指定的次序被更新。這實際上只有連同 limit 一起才有用。

從 mysql 4.0.4 開始,你也可以執(zhí)行一個包含多個表的 update 的操作:

update items,month set items.price=month.pricewhere items.id=month.id;

注意:多表 update 不可以使用 order by 或 limit。
6.4.6 delete 句法


delete [low_priority] [quick] from table_name [where where_definition] [order by ...] [limit rows]ordelete [low_priority] [quick] table_name[.*] [, table_name[.*] ...] from table-references [where where_definition]ordelete [low_priority] [quick] from table_name[.*] [, table_name[.*] ...] using table-references [where where_definition]

delete 從 table_name 中刪除 where_definition 中給定條件的記錄行,并返回刪除的記錄數(shù)目。

如果你發(fā)出一個沒有 where 子句的 delete,所有的記錄行將被刪除。如果你以 autocommit 模式執(zhí)行它,那么它類似于 truncate。查看章節(jié) 6.4.7 truncate 句法。在 mysql 3.23 中,沒有一個 where 子句的 delete 將返回零作為受影響的記錄數(shù)目。

當你刪除所有記錄行時,如果你真的希望知道多少條記錄被刪除,你可以使用一個這種形式的 delete 語句:

mysql> delete from table_name where 1>0;

注意,這將比一個沒有 where 子句的 delete from table_name 語句慢,因為它一次只刪除一行。

如果你指定關鍵詞 low_priority,delete 的執(zhí)行將被延遲,直到?jīng)]有其它的客戶端正在讀取表。

如果你指定關鍵詞 quick,那么在刪除過程中存儲引擎將不會歸并索引葉,這可能會加速某些類型的刪除操作。

在 myisam 表中,刪除了的記錄被放在一個鏈接表中維護,以后的 insert 操作將重新使用刪除后的記錄位置。為了回收閑置的空間,并減小文件尺寸,使用 optimize table 語句或 myisamchk 實用程序重新組織表。optimize table 使用比較容易,但是 myisamchk 更快點。查看章節(jié) 4.5.1 optimize table 句法 和章節(jié) 4.4.6.10 表優(yōu)化。

第一個多表刪除格式從 mysql 4.0.0 開始被支持。第二個多表刪除格式從 mysql 4.0.2 開始被支持。

僅僅在 from 或 using 子句 之前 列出的表中的匹配記錄行被刪除。效果就是,你要以從多個表中同時刪除記錄行,并且同樣可以有其它的表用于檢索。

在表名后的 .* 僅僅是為了兼容 access:

delete t1,t2 from t1,t2,t3 where t1.id=t2.id and t2.id=t3.idordelete from t1,t2 using t1,t2,t3 where t1.id=t2.id and t2.id=t3.id

在上面的情況下,我們僅僅從 t1 和 t2 表中刪除匹配的記錄行。

如果一個 order by 子句被使用(從 mysql 4.0.0 開始支持), 記錄行將以指定的次序刪除。這實際上只有連同 limit 一起才有用。示例如下:

delete from somelogwhere user = 'jcole'order by timestamplimit 1

這將刪除匹配 where 子句的,并且最早被插入(通過 timestamp 來確定)的記錄行。

delete 語句的limit rows 選項是 mysql 特有的,它告訴服務器在控制權(quán)被返回到客戶端之前可被刪除的最大記錄行數(shù)目。這可以用來確保一個特定的 delete 命令不會占用太長的時間。你可以簡單地重復使用 delete 命令,直到被影響的記錄行數(shù)目小于 limit 值。

從 mysql 4.0 開始,在 delete 語句中可以指定多個表,用以從一個表中刪除依賴于多表中的特殊情況的記錄行。然而,在一個多表刪除中,不能使用 order by 或 limit。
6.4.7 truncate 句法


truncate table table_name

在 3.23 中,truncate table 被映射為 commit ; delete from table_name。查看章節(jié) 6.4.6 delete 句法。

在下面的方式中,truncate table 不同于 delete from ...:
刪簡操作撤銷并重建表,這將比一個接一個地刪除記錄行要快得多。非事務安全的;如果存在一個活動的事務或一個有效的表鎖定,你將會得到一個錯誤。不返回刪除了的記錄行數(shù)目。只要表定義文件 `table_name.frm' 是有效的,即使數(shù)據(jù)或索引文件已經(jīng)被損壞,也可以通過這種方式重建表。
truncate 是一個 oracle sql 的擴展。
6.4.8 replace句法


replace [low_priority | delayed] [into] tbl_name [(col_name,...)] values (expression,...),(...),...or replace [low_priority | delayed] [into] tbl_name [(col_name,...)] select ...or replace [low_priority | delayed] [into] tbl_name set col_name=expression, col_name=expression,...

replace 功能與 insert 完全一樣,除了如果在表中存在一個老的記錄與新記錄在一個 unique 或 primary key 上有相同的值,那么在新記錄被插入之前,老的記錄將被刪除。查看章節(jié) 6.4.3 insert 句法。

換句話說,你不可以從一個 replace 中訪問老的記錄行的值。某些老的 mysql 版本中,你或許可以這樣做,但是這是一個 bug,現(xiàn)在已被修正了。

為了能夠使用 replace,你必須有對該表的 insert 和 delete 權(quán)限。

當你使用一個 replace 時,如果新的記錄行代替了老的記錄行,mysql_affected_rows() 將返回 2。這是因為在新行被插入之前,重復記錄行被先刪除了。

這個事實使得判斷 replace 是否是添加一條記錄還是替換一條記錄很容易:檢查受影響記錄行的值是 1 (添加)還是 2(替換)。

注意,除非你使用一個 unique 索引或 primary key ,使用 replace 命令是沒有感覺的,因為它會僅僅執(zhí)行一個 insert。
6.4.9 load data infile 句法


load data [low_priority | concurrent] [local] infile 'file_name.txt' [replace | ignore] into table tbl_name [fields [terminated by '/t'] [[optionally] enclosed by ''] [escaped by '//' ] ] [lines terminated by '/n'] [ignore number lines] [(col_name,...)]

load data infile 語句以非常高的速度從一個文本文件中讀取記錄行并插入到一個表中。如果 local 關鍵詞被指定,文件從客戶端主機讀取。如果 local 沒有被指定,文件必須位于服務器上。(local 在 mysql 3.22.6 或更新的版本中被支持。)

由于安全性的原因,當讀取位于服務器端的文本文件時,文件必須處于數(shù)據(jù)庫目錄或可被所有人讀取的地方。同時,為了對服務器端的文件使用 load data infile,你必須在服務器主機上有 file 權(quán)限。查看章節(jié) 4.2.7 由 mysql 提供的權(quán)限。

在 mysql 3.23.49 和 mysql 4.0.2 中,只有當你沒有以 --local-infile=0 選項啟動 mysqld,或你沒有禁止你的客戶端程序支持 local的情況下,local 才會工作。查看章節(jié) 4.2.4 load data local 的安全性問題.

如果你指定關鍵詞 low_priority,load data 語句的執(zhí)行將會被延遲,直到?jīng)]有其它的客戶端正在讀取表。

如果你對一個 myisam 表指定關鍵詞 concurrent,那么當 load data正在執(zhí)行時,其它的線程仍可以從表中檢索數(shù)據(jù)。使用這個選項時,如果同時也有其它的線程正在使用表,這當然會有一點影響 load data 的執(zhí)行性能。

使用 local 將比讓服務器直接訪問文件要慢一些,因為文件的內(nèi)容必須從客戶端主機傳送到服務器主機。而在另一方面,你不再需要有 file 權(quán)限用于裝載本地文件。

如果你使用先于 mysql 3.23.24 的版本,你不能夠以 load data infile 讀取一個 fifo 。如果你需要從一個 fifo (例如,gunzip 的輸出文件) 中讀取,可以使用 load data local infile 代替。

你也可以使用 mysqlimport 實用程序裝載數(shù)據(jù)文件;它通過發(fā)送一個 load data infile 命令到服務器來動作。--local 選項使得 mysqlimport 從客戶端主機讀取數(shù)據(jù)文件。如果客戶端與服務器支持壓縮協(xié)議,你可以指定 --compress 選項,以在較慢的網(wǎng)絡中獲得更好的性能。

當從服務器主機定位文件時,服務器使用下列規(guī)則:
如果給定一個完整的路徑,服務器使用該路徑名。如果給定一個有一個或多個前置構(gòu)件的相對路徑,服務器以相對服務器的數(shù)據(jù)目錄搜索文件。如果給定一個沒有前置構(gòu)件的文件名,服務器從當前數(shù)據(jù)庫的數(shù)據(jù)庫目錄搜尋文件。
注意,這些規(guī)則意味著,一個以 `./myfile.txt' 給出的文件是從服務器的數(shù)據(jù)目錄中讀取的,然而,以 `myfile.txt' 給出的一個文件是從當前數(shù)據(jù)庫的數(shù)據(jù)目錄下讀取的。舉例來說,下面的 load data 語句從 db1 數(shù)據(jù)庫目錄下讀取文件 `data.txt',因為 db1 是當前數(shù)據(jù)庫,即使該語句明確地指定讀取的文件被放入到 db2 數(shù)據(jù)庫中的一個表中:

mysql> use db1;mysql> load data infile "data.txt" into table db2.my_table;

replace 和 ignore 關鍵詞控制對與現(xiàn)有的記錄在唯一鍵值上重復的記錄的處理。如果你指定 replace,新的記錄行將替換有相同唯一鍵值的現(xiàn)有記錄行。如果你指定 ignore,將跳過與現(xiàn)有的記錄行在唯一鍵值上重復的輸入記錄行。如果你沒有指定任何一個選項,當重復鍵值出現(xiàn)時,將會發(fā)生一個錯誤,文本文件的剩余部分也將被忽略。

如果你使用 local 關鍵詞從一個本地文件中讀取數(shù)據(jù),在此操作過程中,服務器沒有辦法停止文件的傳送,因此缺省的處理方式就好像是 ignore 被指定一樣。

如果你在一個空的 myisam 表上使用 load data infile,所有非唯一索引會以一個分批方式被創(chuàng)建(就像 repair)。當有許多索引時,這通常可以使 load data infile 更快一些。

load data infile 的 select ... into outfile 的逆操作。查看章節(jié) 6.4.1 select 句法。使用 select ... into outfile 將數(shù)據(jù)從一個數(shù)據(jù)庫寫到一個文件中。使用 load data infile 讀取文件到數(shù)據(jù)庫中。兩個命令的 fields 和 lines 子句的句法是一樣的。兩個子句都是可選的,但是如果兩個同時被指定,fields 子句必須出現(xiàn)在 lines 子句之前。

如果你指定一個 fields 子句,它的子句 (terminated by、[optionally] enclosedby 和 escaped by) 也是可選的,不過,你必須至少指定它們中的一個。

如果你沒有指定一個 fields 子句,缺省的相同于如果你這樣寫:

fields terminated by '/t' enclosed by '' escaped by '//'

如果你沒有指定一個 lines 子句,缺省的相同于如果你這樣寫:

lines terminated by '/n'

換句話說,當讀取輸入時,缺省值導致 load data infile 表現(xiàn)如下:
在換行符處尋找行的邊界。在定位符處將行分開放到字段中。不認為字段由任何引號字符封裝。將有 “/” 開頭的定位符、換行符或 `/' 解釋為字段值的一個文字字符。
相反的,當寫入輸出時,缺省值導致 select ... into outfile 表現(xiàn)如下:
在字段值間加上定位符。不用任何引號字符封裝字段。使用 “/” 轉(zhuǎn)義出現(xiàn)在字段值中的定位符、換行符或 `/' 字符實例。在行的結(jié)尾處加上換行符。
注意,為了寫 fields escaped by '//',你必須指定兩個反斜線,該值會作為一個反斜線被讀入。

ignore number lines 選項可被用于忽略文件開頭處的一個列名的頭:

mysql> load data infile "/tmp/file_name" into table test ignore 1 lines;

當你一前一后地使用 select ... into outfile 和 load data infile 將數(shù)據(jù)從一個數(shù)據(jù)庫寫到一個文件中,然后再從文件中將它讀入數(shù)據(jù)庫中時,兩個命令的字段和行處理選項必須匹配。否則,load data infile 將不能正確地解釋文件內(nèi)容。假設你使用 select ... into outfile 以逗號分隔字段的方式將數(shù)據(jù)寫入到一個文件中:

mysql> select * into outfile 'data.txt' -> fields terminated by ',' -> from ...;

為了將由逗號分隔的文件讀回時,正確的語句應該是:

mysql> load data infile 'data.txt' into table table2 -> fields terminated by ',';

如果你試圖用下面所示的語句讀取文件,它將不會工作,因為命令 load data infile 以定位符區(qū)分字段值:

mysql> load data infile 'data.txt' into table table2 -> fields terminated by '/t';

可能的結(jié)果是每個輸入行將被解釋為一個單獨的字段。

load data infile 也可以被用來讀取從外部來源獲得的文件。例如,dbase 格式的文件,字段以逗號分隔并以雙引號包圍著。如果文件中的行以一個換行符終止,那么下面所示的可以說明你將用來裝載文件的字段和行處理選項:

mysql> load data infile 'data.txt' into table tbl_name -> fields terminated by ',' enclosed by '"' -> lines terminated by '/n';

任何字段和行處理選項都可以指定一個空字符串('')。如果不是空的,fields [optionally] enclosed by 和 fields escaped by 值必須是一個單個字符。fields terminated by 和 lines terminated by 值可以超過一個字符。例如,為了寫入由回車換行符終止的行,或讀取包含這樣的行的文件,應該指定一個 lines terminated by '/r/n' 子句。

舉例來說,為了讀取一個文件到一個 sql 表中,文件以一行 %% 分隔(開玩笑的),你可以這樣做:

create table jokes (a int not null auto_increment primary key, joke textnot null);load data infile "/tmp/jokes.txt" into table jokes fields terminated by ""lines terminated by "/n%%/n" (joke);

fields [optionally] enclosed by 控制字段的包圍字符。對于輸出 (select ... into outfile),如果你省略單詞 optionally,所有的字段被 enclosed by 字符包圍。這樣的一個輸出文件(以一個逗號作為字段分界符)示例如下:

"1","a string","100.20""2","a string containing a , comma","102.20""3","a string containing a /" quote","102.20""4","a string containing a /", quote and comma","102.20"

如果你指定 optionally,enclosed by 字符僅被作用于包圍 char 和 varchar 字段:

1,"a string",100.202,"a string containing a , comma",102.203,"a string containing a /" quote",102.204,"a string containing a /", quote and comma",102.20

注意,在一個字段值中出現(xiàn)的 enclosed by 字符,通過用 escaped by 字符作為其前綴對其轉(zhuǎn)義。同時也要注意,如果你指定一個空的 escaped by 值,可能會產(chǎn)生不能被 load data infile 正確讀出的輸出文件。例如,如果轉(zhuǎn)義字符為空,上面顯示的輸出將變成如下顯示的輸出。請注意第四行的第二個字段,它包含一個逗號跟在一個引號后的兩個字符,這(錯誤的)看起來像是一個字段的終止:

1,"a string",100.202,"a string containing a , comma",102.203,"a string containing a " quote",102.204,"a string containing a ", quote and comma",102.20

對于輸入,enclosed by 字符如果存在,它將從字段值的尾部被剝離。(不管 optionally 是否被指定,都是這樣;對于輸入解釋,optionally 不會影響它。) 由escaped by 字符領先于 enclosed by 字符的出現(xiàn),將被解釋為當前字段值的一部分。另外,在字段中出現(xiàn)的重復的 enclosed by 字符被解釋為單個 enclosed by ,只要字段本身也是以該字符開始的。例如,如果 enclosed by '"' 被指定,引號將做如下處理:

"the ""big"" boss" -> the "big" bossthe "big" boss -> the "big" bossthe ""big"" boss -> the ""big"" boss

fields escaped by 控制如何寫入或讀出特殊字符。如果 fields escaped by 字符不是空的,它將被用于做為下列輸出字符的前綴:fields escaped by 字符fields [optionally] enclosed by 字符fields terminated by 和 lines terminated by 值的第一個字符。ascii 0 (實際上在轉(zhuǎn)義字符后寫上 ascii '0',而不是一個零值字節(jié))
如果 fields escaped by 字符為空,沒有字符被轉(zhuǎn)義。指定一個空的轉(zhuǎn)義字符可能不是一個好的主意,特別是如果你的數(shù)據(jù)字段值中包含剛才列表中的任何字符時。

對于輸入,如果 fields escaped by 字符不為空,該字符的出現(xiàn)將會被剝離,后續(xù)的字符在字面上做為字段值的一部分。除了一個轉(zhuǎn)義的 “0” 或 “n” (即,/0 或/n,如果轉(zhuǎn)義字符為 `/')。這些序列被解釋為 ascii 0 (一個零值字節(jié)) 和 null。查看下面的有關 null 處理的規(guī)則。

關于更多的 “/” 轉(zhuǎn)義句法信息,查看章節(jié) 6.1.1 文字:怎么寫字符串與數(shù)字。

在某些情況下,字段與行處理相互作用:
如果 lines terminated by 是一個空字符串,fields terminated by 是非空的,行也用 fields terminated by 終止。如果 fields terminated by 和 fields enclosed by 值都是空的 (''),一個固定行(無定界符) 格式被使用。用固定行格式時,在字段之間不使用分隔符。代替的,列值的寫入和讀取使用列的“顯示”寬度。例如,如果一個列被定義為 int(7),列的值將使用 7 個字符的字段被寫入。對于輸入,列值通過讀取 7 個字符來獲得。固定行格式也影響對 null 值的處理;見下面。注意,如果你正在使用一個多字節(jié)的字符集,固定長度格式將不能工作。
null 值的處理有很多,取決于你所使用的 fields 和 lines 選項:
對于缺省的 fields 和 lines 值,輸出時,null 被寫成 /n,當讀入時,/n 被作為 null 讀入(假設 escaped by 字符為 “/”)。如果 fields enclosed by 是非空的,一個字段包含文字詞 null 的,它的值做為一個 null 值被讀入 (這不同于被 fields enclosed by 包圍的詞 null,它是被作為 'null' 讀入的)。如果 fields escaped by 是空的,null 值被寫為詞 null。用固定行格式時 (它發(fā)生于 fields terminated by 和 fields enclosed by 兩者均為空),null 被寫為一個空的字符串。注意,當將表中的 null 值和空字符串一起寫到文件中時,它們將被混淆,因為它們都是作為空字符串被寫入的。如果你在文件時,需要對他們兩個進行區(qū)分,你不應該使用固定行格式。
一些不能被 load data infile 支持的情況:固定尺寸的記錄行 (fields terminated by 和 fields enclosed by 均為空) 和 blob 或 text 列。如果你指定一個分隔符與另一個相同,或是另一個的前綴,load data infile 可能會不能正確地解釋輸入。例如,下列的 fields 子句將會產(chǎn)生問題:
fields terminated by '"' enclosed by '"'
如果 fields escaped by 為空,一個字段值中包含有 fields enclosed by 或 lines terminated by 被 fields terminated by 跟隨的值時,將會引起 load data infile 過早地停止讀取一個字段或一行。這是因為 load data infile 不能夠正確地決定字段或行值在哪里結(jié)果。
下面的例子將裝載 persondata 表的所有列:

mysql> load data infile 'persondata.txt' into table persondata;

沒有字段列被指定,因而 load data infile 認為輸入行包含表列中所有的字段。使用缺省的 fields 和lines 值。

如果你希望裝載表中的某些列,那指定一個字段列表:

mysql> load data infile 'persondata.txt' -> into table persondata (col1,col2,...);

如果輸入文件的字段次序不同于表中列的順序,你也必須指定一個字段列表。否則 mysql 不知道如何將輸入字段與表中的列匹配。

如果一個行有很少的字段,沒有輸入字段的列將被設置為缺省值。缺省值賦值在章節(jié) 6.5.3 create table 句法 中被描述。

一個空的字段值不同于字段值丟失的解釋:
對于字符串類型,列被設置為空字符串。對于數(shù)字類型,列被設置為 0。對于日期和時間類型,列被設置為適合列類型的“零”值。查看章節(jié) 6.2.2 date 和 time 類型。
注意,如果在一個 insert 或 update 語句中明確地將一個空字符串賦給一個字符串、數(shù)字或日期或時間類型,你會得到與上面相同的結(jié)果。

如果對 timestamp 列指定一個 null 值,或者當字段列表被指定時, timestamp 在字段列表中被遺漏(僅僅第一個 timestamp 列被影響),timestamp 列會被設置為當前的日期和時間。

如果輸入的記錄行有太多的字段,多余的字段將被忽略,并增加警告的數(shù)目。

load data infile 認為所有的輸入均是字符串,因而,對于 enum 或 set 列,你不能以 insert 語句的形式為其設置數(shù)字值。所有的 enum 和 set 必須以字符串指定!

如果你正在使用 c api,當 load data infile 查詢結(jié)束時,你可以調(diào)用 api 函數(shù) mysql_info() 獲得有關查詢的信息。信息串的格式如下:

records: 1 deleted: 0 skipped: 0 warnings: 0

警告會在某些情況下發(fā)生,這些情況與值通過 insert 語句插入時發(fā)生警告的情況一樣 (查看章節(jié) 6.4.3 insert 句法),但是 load data infile 有一點與它不一樣,當在輸入行中有太多或過少的字段,它也會產(chǎn)生警告。警告不會被存儲在任何地主;警告的數(shù)目僅能表示一切是否順利。如果得到警告,并希望確切地知道為什么會得到它們,一個方法就是使用 select ... into outfile,將它保存到另外一個文件中,并與原先的輸入文件進行比較。

如果你需要 load data 從一個管道中讀取,你可以使用下面的技巧:

mkfifo /mysql/db/x/xchmod 666 /mysql/db/x/xcat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/xmysql -e "load data infile 'x' into table x" x

如果你使用的版本早于 mysql 3.23.25,你只能通過 load data local infile 來執(zhí)行上面。

有關 insert 相對 load data infile 的效率和加快 load data infile 的更多信息,請查看章節(jié) 5.2.9 insert 查詢的速度。
6.4.10 do 句法


do expression, [expression, ...]

執(zhí)行表達式,但不返回任何結(jié)果。這是 select expression, expression 的一個縮寫,但是當你并不關心結(jié)果時,它稍有點優(yōu)勢,因為它稍稍快一點。

這主要有益于有副作用的函數(shù),比如 release_lock。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 成安县| 清苑县| 拉萨市| 崇州市| 泸定县| 惠东县| 中阳县| 樟树市| 舒兰市| 象州县| 阜康市| 曲麻莱县| 浙江省| 洪雅县| 方城县| 永州市| 安乡县| 甘南县| 海兴县| 固阳县| 大关县| 泸溪县| 神农架林区| 建宁县| 天津市| 新丰县| 嘉禾县| 昌乐县| 攀枝花市| 图木舒克市| 泊头市| 永吉县| 江城| 独山县| 元谋县| 家居| 漯河市| 华宁县| 枣阳市| 塘沽区| 天全县|