Like Share Discussion Bookmark Smile

J.J. Huang   2020-07-11   MySQL   瀏覽次數:次   DMCA.com Protection Status

MySQL - 第二十章 | 插入資料(上)

如何利用SQL的INSERT語句將資料插入表中。

資料插入

毫無疑問,SELECT是最常使用的SQL語句了。

顧名思義,INSERT是用來插入(或添加)行到資料庫表的。插入可以用幾種方式使用:

  • 插入完整的行;
  • 插入行的一部分;
  • 插入多行;
  • 插入某些查詢的結果。

提示:插入及系統安全 可針對每個表或每個用戶,利用MySQL的安全機制禁止使用INSERT語句。

插入完整的行

把資料插入表中的最簡單的方法是使用基本的INSERT語法,它要求指定表名和被插入到新行中的值。

1
2
mysql> INSERT INTO customers VALUES(NULL, 'Pep E. LaPwe', '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA', NULL, NULL);
Query OK, 1 row affected (0.10 sec)

說明:沒有輸出 INSERT語句一般不會產生輸出。

分析:插入一個新客戶到customers表。存儲到每個表列中的資料在VALUES子句中給出,對每個列必須提供一個值。如果某個列沒有值(如上面的cust_contact和cust_email列),應該使用NULL值(假定表允許對該列指定空值)。各個列必須以它們在表定義中出現的次序填充。第一列cust_id也為NULL。這是因為每次插入一個新行時,該列由MySQL自動增量。你不想給出一個值(這是MySQL的工作),又不能省略此列(如前所述,必須給出每個列),所以指定一個NULL值(它被MySQL忽略,MySQL在這裡插入下一個可用的cust_id值)。

雖然這種語法很簡單,但並不安全,應該盡量避免使用。上面的SQL語句高度依賴於表中列的定義次序,並且還依賴於其次序容易獲得的訊息。即使可得到這種次序訊息,也不能保證下一次表結構變動後各個列保持完全相同的次序。因此,編寫依賴於特定列次序的SQL語句是很不安全的。如果這樣做,有時難免會出問題。

1
2
mysql> INSERT INTO `testdb`.`customers` (`cust_name`, `cust_address`, `cust_city`, `cust_state`, `cust_zip`, `cust_country`, `cust_contact`, `cust_email`) VALUES ('Pep E. LaPwe', '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA', NULL, NULL);
Query OK, 1 row affected (0.05 sec)

分析:完成與前一個INSERT語句完全相同的工作,但在表名後的括號里明確地給出了列名。在插入行時,MySQL將用VALUES列表中的相應值填入列表中的對應項。VALUES中的第一個值對應於第一個指定的列名。第二個值對應於第二個列名,如此等等。

因為提供了列名,VALUES必須以其指定的次序匹配指定的列名,不一定按各個列出現在實際表中的次序。其優點是,即使表的結構改變,此INSERT語句仍然能正確工作。你會發現cust_id的NULL值是不必要的,cust_id列並沒有出現在列表中,所以不需要任何值。

下面的INSERT語句填充所有列(與前面的一樣),但以一種不同的次 序填充。因為給出了列名,所以插入結果仍然正確。

1
2
mysql> INSERT INTO `testdb`.`customers` (`cust_name`, `cust_contact`, `cust_email`, `cust_address`, `cust_city`, `cust_state`, `cust_zip`, `cust_country`) VALUES ('Pep E. LaPwe', NULL, NULL, '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA');
Query OK, 1 row affected (0.01 sec)

提示:總是使用列的列表 一般不要使用沒有明確給出列的列表的INSERT語句。使用列的列表能使SQL代碼繼續發揮作用,即使表結構發生了變化。

注意:仔細地給出值 不管使用哪種INSERT語法,都必須給出VALUES的正確數目。如果不提供列名,則必須給每個表列提供一個值。如果提供列名,則必須對每個列出的列給出一個值。如果不這樣,將產生一條錯誤消息,相應的行插入不成功。

使用這種語法,還可以省略列。這表示可以只給某些列提供值,給其他列不提供值。(事實上你已經看到過這樣的例子:當列名被明確列出時,cust_id可以省略。)

注意:省略列 如果表的定義允許,則可以在INSERT操作中省略某些列。省略的列必須滿足以下某個條件。1. 該列定義為允許NULL值(無值或空值)。2. 在表定義中給出默認值。這表示如果不給出值,將使用默認值。如果對表中不允許NULL值且沒有默認值的列不給出值,則MySQL將產生一條錯誤消息,並且相應的行插入不成功。

提示:提高整體性能 資料庫經常被多個客戶訪問,對處理什麼請求以及用什麼次序處理進行管理是MySQL的任務。INSERT操作可能很耗時(特別是有很多索引需要更新時),而且它可能降低等待處理的SELECT語句的性能。如果資料檢索是最重要的(通常是這樣),則你可以通過在INSERT和INTO之間添加關鍵字LOW_PRIORITY,指示MySQL降低INSERT語句的優先級。(這也適用於UPDATE和DELETE語句)

1
INSERT LOW_PRIORITY INTO

結語

因為現在使用很多的ORM來做資料庫的操作,所以比較少寫INSERT的語法,但是其中我覺得比較重要的部分是,在INSERT的時候,要指定對應每個列,因為在未來可能表的結構有變動也不影響。

另外LOW_PRIORITY的部分,這部分可以針對一些不是非常重要和即時性的資料下此語法。

題外話:物件關聯對映(英語:Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程式設計技術,用於實現物件導向編程語言裡不同類型系統的資料之間的轉換。 從效果上說,它其實是創建了一個可在編程語言裡使用的“虛擬物件資料庫”。

註:以上參考了
MySQL必知必会 MySQL Crash Course