標籤:sunday 其他 插入行 組合 系統安全 就是 customer 技術分享 依賴
第19章-插入資料
本章介紹如何利用SQL的INSERT語句將資料插入表中。
19.1 資料插入
毫無疑問, SELECT是最常使用的SQL語句了(這就是為什麼前17章講的都是它的原因)。但是,還有其他3個經常使用的SQL語句需要學習。第一個就是INSERT(下一章介紹另外兩個)。顧名思義, INSERT是用來插入(或添加)行到資料庫表的。插入可以用幾種方式使用:
- 插入完整的行;
- 插入行的一部分;
- 插入多行;
- 插入某些查詢的結果。
下面將介紹這些內容。
插入及系統安全 可針對每個表或每個使用者,利用MySQL的安全機制禁止使用INSERT語句,這將在第28章介紹。
19.2 插入完整的行
把資料插入表中的最簡單的方法是使用基本的INSERT文法,它要求177132 指定表名和被插入到新行中的值。下面舉一個例子:
沒有輸出 INSERT語句一般不會產生輸出。
此例子插入一個新客戶到customers表。儲存到每個表列中的資料在VALUES子句中給出,對每個列必須提供一個值。如果某個列沒有值(如上面的cust_contact和cust_email列),應該使用NULL值(假定表允許對該列指定空值)。各個列必須以它們在表定義中出現的次序填充。第一列cust_id也為NULL。這是因為每次插入一個新行時,該列由MySQL自動增量。你不想給出一個值(這是MySQL的工作),又不能省略此列(如前所述,必須給出每個列),所以指定一個NULL值(它被MySQL忽略, MySQL在這裡插入下一個可用的cust_id值)。雖然這種文法很簡單,但並不安全,應該盡量避免使用。上面的SQL語句高度依賴於表中列的定義次序,並且還依賴於其次序容易獲得的資訊。即使可得到這種次序資訊,也不能保證下一次表結構變動後各個列保持完全相同的次序。因此,編寫依賴於特定列次序的SQL語句是很不安全的。如果這樣做,有時難免會出問題。編寫INSERT語句的更安全(不過更煩瑣)的方法如下:
此例子完成與前一個INSERT語句完全相同的工作,但在表名後的括弧裡明確地給出了列名。在插入行時, MySQL將用VALUES列表中的相應值填入列表中的對應項。 VALUES中的第一個值對應於第一個指定的列名。第二個值對應於第二個列名,如此等等。因為提供了列名, VALUES必須以其指定的次序匹配指定的列名,不一定按各個列出現在實際表中的次序。其優點是,即使表的結構改變,此INSERT語句仍然能正確工作。你會發現cust_id的NULL值是不必要的,cust_id列並沒有出現在列表中,所以不需要任何值。下面的INSERT語句填充所有列(與前面的一樣),但以一種不同的次序填充。因為給出了列名,所以插入結果仍然正確:
總是使用列的列表 一般不要使用沒有明確給出列的列表的INSERT語句。使用列的列表能使SQL代碼繼續發揮作用,即使表結構發生了變化。
仔細地給出值 不管使用哪種INSERT文法,都必須給出VALUES的正確數目。如果不提供列名,則必須給每個表列提供一個值。如果提供列名,則必須對每個列出的列給出一個值。如果不這樣,將產生一條錯誤訊息,相應的行插入不成功。使用這種文法,還可以省略列。這表示可以只給某些列提供值,給其他列不提供值。(事實上你已經看到過這樣的例子:當列名被明確列出時, cust_id可以省略。)
省略列 如果表的定義允許,則可以在INSERT操作中省略某些列。省略的列必須滿足以下某個條件。
- 該列定義為允許NULL值(無值或空值)。
- 在表定義中給出預設值。這表示如果不給出值,將使用預設值。
如果對錶中不允許NULL值且沒有預設值的列不給出值,則MySQL將產生一條錯誤訊息,並且相應的行插入不成功。
提高整體效能 資料庫經常被多個客戶訪問,對處理什麼請求以及用什麼次序處理進行管理是MySQL的任務。 INSERT操作可能很耗時(特別是有很多索引需要更新時),而且它可能降低等待處理的SELECT語句的效能。如果資料檢索是最重要的(通常是這樣),則你可以通過在INSERT和INTO之間添加關鍵字LOW_PRIORITY,指示MySQL降低INSERT語句的優先順序,如下所示:
INSERT LOW_PRIORITY INTO
順便說一下,這也適用於下一章介紹的UPDATE和DELETE語句。
19.3 插入多個行
INSERT可以插入一行到一個表中。但如果你想插入多個行怎麼辦?
可以使用多條INSERT語句,甚至一次提交它們,每條語句用一個分號結束,如下所示:
或者,只要每條INSERT語句中的列名(和次序)相同,可以如下組合各語句:
其中單條INSERT語句有多組值,每組值用一對圓括弧括起來,用逗號分隔。
提高INSERT的效能 此技術可以提高資料庫處理的效能,因為MySQL用單條INSERT語句處理多個插入比使用多條INSERT語句快。
19.4 插入檢索出的資料
INSERT一般用來給表插入一個指定列值的行。但是, INSERT還存在另一種形式,可以利用它將一條SELECT語句的結果插入表中。這就是所謂的INSERT SELECT,顧名思義,它是由一條INSERT語句和一條SELECT語句組成的。假如你想從另一表中合并客戶列表到你的customers表。 不需要每次讀取一行,然後再將它用INSERT插入,可以如下進行:
新例子的說明 這個例子把一個名為custnew的表中的資料匯入customers表中。為了實驗這個例子,應該首先建立和填充custnew表。 custnew表的結構與附錄B中描述的customers表的相同。在填充custnew時,不應該使用已經在customers中使用過的cust_id值(如果主索引值重複,後續的INSERT操作將會失敗)或僅省略這列值讓MySQL在匯入資料的過程中產生新值。
這個例子使用INSERT SELECT從custnew中將所有資料匯入customers。 SELECT語句從custnew檢索出要插入的值,而不是列出它們。 SELECT中列出的每個列對應於customers表名後所跟的列表中的每個列。這條語句將插入多少行有賴於custnew表中有多少行。如果這個表為空白,則沒有行被插入(也不產生錯誤,因為操作仍然是合法的)。如果這個表確實含有資料,則所有資料將被插入到customers。這個例子匯入了cust_id(假設你能夠確保cust_id的值不重複)。你也可以簡單地省略這列(從INSERT和SELECT中),這樣MySQL就會產生新值。
INSERT SELECT中的列名 為簡單起見,這個例子在INSERT和SELECT語句中使用了相同的列名。但是,不一定要求列名匹配。事實上, MySQL甚至不關心SELECT返回的列名。它使用的是列的位置,因此SELECT中的第一列(不管其列名)將用來填充表列中指定的第一個列,第二列將用來填充表列中指定的第二個列,如此等等。這對於從使用不同列名的表中匯入資料是非常有用的。INSERT SELECT中SELECT語句可包含WHERE子句以過濾插入的資料。
更多例子 如果想看INSERT用法的更多例子,請參閱附錄B中給出的範例表填充指令碼,這主要用於建立本書中使用的範例表。
19.5 小結
本章介紹如何將行插入到資料庫表。我們學習了使用INSERT的幾種方法,以及為什麼要明確使用列名,學習了如何用INSERT SELECT從其他表中匯入行。下一章講述如何使用UPDATE和DELETE進一步操縱表資料。
MySQL必知應會-第19章-插入資料