UPDATE

Name

UPDATE -- 更新一個資料表中的行

Synopsis

UPDATE [ ONLY ] table SET column = { expression | DEFAULT } [, ...]
    [ FROM fromlist ]
    [ WHERE condition ]

描述

UPDATE 改變滿足條件的所有行的聲明了的列/字串的值。 只有要更改的列/字串需要在 SET 子句中出現,沒有明確修改的字串保持它們原來的數值。

預設時,UPDATE 將更新所聲明的資料表和所有子資料表的記錄。 如果您希望只更新所聲明的資料表,您應該使用 ONLY 子句。

使用存在於同個資料庫裡其它資料表的訊息來更新一個資料表,有兩種方法可以用: 使用子查詢,或者在 FROM 子句裡聲明另外一個資料表。 哪個方法更好取決於具體的環境。

要更改資料表,您必須對它有UPDATE 權限, 同樣對 expression 或者 condition 條件裡提到的任何資料表也要有SELECT權限。

參數

table

現存資料表的名稱(可以有模式修飾)。

column

資料表 table 中字串名。 必要時,字串名可以用子域名或者數組下標修飾。

expression

賦予列/字串的一個有效的值或資料表達式。資料表達式可以使用資料表中這個或其它字串的舊數值。

DEFAULT

把字串設置為它的預設值(如果沒有預設資料表達式賦予它,那麼就是 NULL)。

fromlist

一個資料表資料表達式的列資料表,允許來自其它資料表中的字串出現在 WHERE 條件裡。 這個類似於可以在一個 SELECT 語句的 FROM 子句 裡聲明資料表列資料表。請注意目標資料表絕對不能出現在 fromlist 裡, 除非您是在使用一個自連接(這個時候,它必須以 fromlist 的一個別名的形式出現)。

condition

一個資料表達式,返回 boolean 類型。只有這個資料表達式返回 true 的行被更新。

輸出

成功完成後,UPDATE 命令返回形如

UPDATE count

的命令標籤。count 是更新的行數。 如果 count 是 0, 那麼沒有符合 condition 的行(這個不認為是錯誤)。

注意

在出現 FROM 子句的時候,實際上發生的事情是目標資料表和 fromlist 裡提到的資料表連接在一起,並且每個連接輸出行都代資料表一個目標資料表的更新操作。 再使用 FROM 的時候,您應該保證連接為每個需要修改的行最多生成一個輸出行。 換句話說,一個目標行不應該和超過一行來自其它資料表的資料行連接。 如果它連接了多於一個行,那麼連接行裡面將會只有一行用於更新目標行, 但是使用哪行是一個很難預期的事情。

因為這個不確定性,只再子查詢裡面引用其它資料表是安全的, 儘管通常更難讀並且比使用連接也更慢些。

例子

把資料表 films 裡的字串 kind 裡的詞 DramaDramatic 代替:

UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';

調整資料表 weather 中的一行的溫度記錄並且把降水設置為預設值:

UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
  WHERE city = 'San Francisco' AND date = '2003-07-03';

增加負責 Acme 公司客戶的銷售的銷售計數,使用 FROM 子句語法:

UPDATE employees SET sales_count = sales_count + 1 FROM accounts
  WHERE accounts.name = 'Acme Corporation'
  AND employees.id = accounts.sales_person;

執行同樣的操作,使用 WHERE 子句裡的子查詢:

UPDATE employees SET sales_count = sales_count + 1 WHERE id =
  (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');

試圖帶著庫存量插入一個新的庫存項。如果該項存在,則更新現有項的庫存數。 要做這件事情而又不使整個交易失效,使用保留點(savepoints)。

BEGIN;
-- 其它操作
SAVEPOINT sp1;
INSERT INTO wines VALUES('Chateau Lafite 2003', '24');
-- 假設上面的因為一個唯一鍵字違反而失效,
-- 因此現在我們發出這些命令:
ROLLBACK TO sp1;
UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003';
-- 繼續其它操作,最後
COMMIT;

相容性

這條命令遵循 SQL 標準。 只是 FROM 子句是 PostgreSQL 擴展。

有些其它資料庫系統提供一個 FROM 選項, 在這個選項下,認為目標資料表會再次在 FROM 裡列出。 這不是 PostgreSQL 解析 FROM 的方式。 移植使用這類擴展的應用的時候要注意。