2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2

6.4. 返回已修改行的 Dati #

有時,在操作行時獲取已修改行的資料非常有用。INSERTUPDATEDELETEMERGE 命令都包含可選的 RETURNING 子句,支援此功能。使用 RETURNING 可以避免執行額外的資料庫查詢來收集資料,當否則難以可靠地識別已修改的行時,尤其有價值。

RETURNING 子句允許的內容與 SELECT 命令的輸出列表相同(參見 Section 7.3)。它可以包含命令目標表的列名,或使用這些列的值表示式。一個常見的簡寫是 RETURNING *,它按順序選擇目標表的所有列。

INSERT 中,RETURNING 可用的預設資料是插入時的行。這在簡單的插入操作中不太有用,因為它只會重複客戶端提供的資料。但當依賴於計算出的預設值時,它可能非常方便。例如,在使用 serial 列提供唯一識別符號時,RETURNING 可以返回分配給新行的 ID。

CREATE TABLE users (firstname text, lastname text, id serial primary key);

INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;

RETURNING 子句對於 INSERT ... SELECT 也非常有用。

UPDATE 中,RETURNING 可用的預設資料是已修改行的最新內容。例如:

UPDATE products SET price = price * 1.10
  WHERE price <= 99.99
  RETURNING name, price AS new_price;

DELETE 中,RETURNING 可用的預設資料是已刪除行的內容。例如:

DELETE FROM products
  WHERE obsoletion_date = 'today'
  RETURNING *;

MERGE 中,RETURNING 可用的預設資料是源行的內容加上已插入、已更新或已刪除的目標行的內容。由於源行和目標行經常有許多相同的列,指定 RETURNING * 可能會導致很多重複的列,因此通常更方便限定它,以便只返回源行或目標行。例如:

MERGE INTO products p USING new_products n ON p.product_no = n.product_no
  WHEN NOT MATCHED THEN INSERT VALUES (n.product_no, n.name, n.price)
  WHEN MATCHED THEN UPDATE SET name = n.name, price = n.price
  RETURNING p.*;

在這些命令中的每一箇中,還可以顯式返回已修改行的舊內容和新內容。例如:

UPDATE products SET price = price * 1.10
  WHERE price <= 99.99
  RETURNING name, old.price AS old_price, new.price AS new_price,
            new.price - old.price AS price_change;

在此示例中,編寫 new.price 與僅編寫 price 相同,但它使含義更清晰。

這種返回舊值和新值的語法在 INSERTUPDATEDELETEMERGE 命令中可用,但對於 INSERT,舊值通常是 NULL,對於 DELETE,新值通常是 NULL。但是,在某些情況下,對於這些命令它仍然有用。例如,在帶有 ON CONFLICT DO UPDATE 子句的 INSERT 中,對於衝突的行,舊值將是非 NULL 的。類似地,如果 DELETE 透過 重寫規則 變成了 UPDATE,則新值可能是 NULL

如果目標表上有觸發器(參見 Chapter 37),則 RETURNING 可用的資料是經觸發器修改後的行。因此,檢查由觸發器計算的列是 RETURNING 的另一個常見用例。

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。