前一章討論了如何建立資料表和其他結構來保存資料。現在是把資料表填滿的時候了。本章介紹如何新增、更新和刪除資料表的資料。 下一章將會完整說明如何從資料庫中取回你遺落在裡面的資料。
將已經在資料庫中的資料做修改被稱為更新。您可以單獨更新某個資料列,或資料表中的所有資料列,或是部份資料列。每個欄位可以單獨更新,而不影響其他欄位。
要更新現有的資料列,請使用 UPDATE 指令。這需要三種資訊:
要更新的資料表和欄位的名稱
資料欄位新的內容
哪些資料列要更新
回想一下第 5 章,SQL 通常不提供資料列的唯一識別資訊。因此,直接指定要更新哪一行通常是不行的,而是指定該資料列必須符合哪些條件才能更新。只有你在資料表中有一個主鍵(決定於是否你有宣告過)之後,才能通過選擇與主鍵相匹配的條件來可靠地解決單個資料列的問題。圖形化的資料庫管理工具依賴這個方式才能允許你單獨更新指定的資料列。
例如,這個指令會將價格為 5 的所有產品更新為 10:
這結果可能是零個,一個或多個資料列被更新。嘗試更新卻沒有匹配到任何資料列,並不是一種錯誤。
我們來詳細看看這個命令。首先是關鍵字 UPDATE,然後是資料表的名稱。像往常一樣,資料表的名稱可以使用加上 schema 的完整路徑名稱,否則就會在搜尋路徑中尋找。接下來的關鍵字是 SET,後面接著欄位名稱,等號和新的欄位內容。新的欄位內容可以是任何的運算表示式,而不僅僅是一個常數。例如,如果要將所有產品的價格提高10%,則可以使用:
如你所見,欄位的表示式可以引用資料列中現有的內容。我們還遺漏了 WHERE 子句。如果省略的話,則意味著資料表中的所有資料列都會被更新。如果存在的話,則只有更新符合 WHERE 條件的那些資料列。請注意,SET 子句中的等號是一個賦值運算,而 WHERE 子句中的等號是比較運算,但這不會造成任何誤解。當然,WHERE 條件不一定是等號運算。 還有許多其他的運算子可以使用(詳見第 9 章)。但是表示式需要能產生為布林運算的結果。
您可以在使用 UPDATE 指令時,以 SET 子句中列出多個欄位賦值來更新多個欄位內容。例如:
到目前為止,我們已經解釋瞭如何將資料新增到資料表以及如何更新資料了。剩下的就是討論如何刪除不再需要的資料。 正如新增資料時只能新增整個資料列一樣,你只能從資料表中以資料列為單位刪除資料。在前面的章節中,我們解釋了SQL沒有提供直接處理某個資料列的方法。因此,只能透過指定要刪除的行必須符合的條件來刪除指定的資料列。如果資料列中有主鍵,則可以指定確切的資料列。但是,你也可以刪除全部符合條件的資料列,更可以一次刪除資料表中的所有資料列。
您使用 DELETE 指令刪除資料列;該語法與 UPDATE 指令十分類似。例如,要從產品表中刪除價格為 10 的所有資料列,請使用:
如果你只是寫:
那麼資料表中的所有資料列都將被刪除! 請程式設計師一定要小心使用。
有時在修改資料列的操作過程中取得資料是很方便的。INSERT、UPDATE 和 DELETE 指令都有一個選擇性的RETURNING 子句來支持這個功能。使用 RETURNING 可以避免執行額外的資料庫查詢來收集資料,特別是在難以可靠地識別修改的資料列時尤其有用。
RETURNING 子句允許的語法與 SELECT 指令的輸出列表相同(詳見第 7.3 節)。它可以包含命令目標資料表的欄位名稱,或者包含使用這些欄位的表示式。常用的簡寫形式是 RETURNING *,預設是資料表的所有欄位,且相同次序。
在 INSERT 中,可用於 RETURNING 的資料是新增的資料列。這在一般的資料新增中並不是很有用,因為它只會重複用戶端所提供的資料。但如果是計算過的預設值就會非常方便。 例如,當使用串列欄位(serial)提供唯一識別時,RETURNING 可以回傳分配給新資料列的 ID:
對於 INSERT ... SELECT,RETURNING 子句也非常有用。
在 UPDATE 中,可用於 RETURNING 的資料是被修改的資料列新內容。例如:
在 DELETE 中,可用於 RETURNING 的資料是已刪除資料列的內容。例如:
如果目標資料表上有觸發函數的話(第 38 章),則可用於 RETURNING 的資料是由該觸發函數所修改的資料列。因此,由觸發函數計算檢查欄位是 RETURNING 的另一個常見用法。
資料表在建立的時候,並不包含任何資料。以各種方式使用資料庫之前,要做的第一件事就是新增資料。概念上,資料是一次新增一列。當然你也可以新增多列,但就沒有辦法新增少於一列。 即使只知道某些欄位的值,也必須建立一個完整的資料列。
要建立新的資料列,請使用 INSERT 指令。該命令需要資料表的名稱和各欄位的資料內容。例如,來看看第 5 章中的產品資料表:
新增資料列的指令可能如下所示:
資料內容按資料表表中欄位的順序列出,以逗號分隔。通常,資料內容會是文字(常數),但運算表示式也是允許的。
上面的語法有缺點,就是你需要知道資料表中欄位的順序。為了避免這種情況,您可以明確地列出欄位。例如,以下兩個命令與上面的命令具有相同的效果:
許多用戶認為總是列出欄位名稱是一個很好的習慣。
如果你並沒有所有欄位的內容,則可以省略其中一些欄位。在這種情況下,那些欄位將會以預設值代入。如下所示:
第二種形式是屬於 PostgreSQL 延伸寫法。 從左邊開始的欄位填入所給定的內容,其餘的欄位則使用預設值。
為了清楚起見,你也可以明確地指定個別欄位或整個資料列都使用預設值:
您可以在一個命令中新增多個資料列:
也可以以查詢的結果新增(可能沒有資料,一個資料列或多個資料列):
這包含完整 SQL 查詢機制(第 7 章)用於計算需要新增的資料列。
同時要新增大量資料時,請考慮使用 COPY 指令。它不像 INSERT 指令那麼靈活,但是效率更高。有關提高批次新增資料效率的更多資訊,請參閱第 14.4 節。