小巧、快速、可靠。
任選三項。
更新

1. 概觀

update-stmt

WITH RECURSIVE common-table-expression , UPDATE OR ROLLBACK qualified-table-name OR REPLACE OR IGNORE OR FAIL OR ABORT SET column-name-list = expr column-name , FROM table-or-subquery , join-clause WHERE expr returning-clause

column-name-list

common-table-expression

expr

join-clause

qualified-table-name

returning-clause

table-or-subquery

UPDATE 陳述式用於修改由 UPDATE 陳述式一部分所指定的 限定表格名稱 所識別的資料庫表格中零或多列儲存值的子集。

2. 詳細資料

如果 UPDATE 陳述式沒有 WHERE 子句,表格中的所有列都會被 UPDATE 修改。否則,UPDATE 僅影響 WHERE 子句 布林表達式為真 的那些列。如果表格中任何列的 WHERE 子句評估結果不為真,這並非錯誤 - 這僅表示 UPDATE 陳述式影響零列。

受 UPDATE 陳述式影響的每一列的修改由 SET 關鍵字後面的指定清單決定。每個指定在等號符號的左側指定一個欄位名稱,在右側指定一個純量表達式。對於每個受影響的列,命名欄位會設定為透過評估對應純量表達式找到的值。如果單一欄位名稱在指定表達式清單中出現多次,除了最右邊的出現之外,其他都會被忽略。未出現在指定清單中的欄位會保持不變。純量表達式可以參考正在更新的列。在這種情況下,所有純量表達式都會在進行任何指定之前評估。

從 SQLite 版本 3.15.0(2016-10-14)開始,SET 子句中的指定可以在左側為括號中的欄位名稱清單,在右側為相同大小的列值

UPDATE 關鍵字後面的選用「OR 動作」衝突子句允許使用者提名一個特定的約束衝突解決演算法,在這個 UPDATE 指令期間使用。請參閱標題為ON CONFLICT的區段,以取得更多資訊。

2.1. 在 CREATE TRIGGER 中對 UPDATE 陳述式的限制

以下額外的語法限制適用於出現在CREATE TRIGGER陳述式主體中的 UPDATE 陳述式。

2.2. UPDATE FROM

UPDATE-FROM 構想是 SQL 的延伸,允許 UPDATE 陳述式由資料庫中的其他 table 驅動。「目標」table 是正在更新的特定 table。使用 UPDATE-FROM,您可以將目標 table 與資料庫中的其他 table 進行聯結,以協助計算哪些列需要更新,以及這些列的新值應該是什麼。UPDATE-FROM 在 SQLite 版本 3.33.0(2020-08-14)中開始支援。

其他關聯資料庫引擎也實作 UPDATE-FROM,但由於此建構不是 SQL 標準的一部分,因此每個產品實作 UPDATE-FROM 的方式都不同。SQLite 實作力求與 PostgreSQL 相容。SQL Server 和 MySQL 對相同概念的實作方式略有不同。

以下是一個 UPDATE-FROM 如何有用的範例,假設您有一個累積 SALES 表格中購買項目的銷售應用程式。在一天結束時,您想要根據每日銷售調整 INVENTORY 表格。為執行此動作,您可以針對 INVENTORY 表格執行 UPDATE,調整每日銷售的數量。陳述式會如下所示

UPDATE inventory
   SET quantity = quantity - daily.amt
  FROM (SELECT sum(quantity) AS amt, itemId FROM sales GROUP BY 2) AS daily
 WHERE inventory.itemId = daily.itemId;

FROM 子查詢會計算每個 itemId 應減少的庫存數量。該子查詢會與庫存表格結合,而每個受影響庫存列的數量會減少適當的數量。

目標表格不會包含在 FROM 子句中,除非目的是對目標表格進行自我結合。在自我結合的情況下,FROM 子句中的表格必須別名為與目標表格不同的名稱。

如果目標表格與 FROM 子句之間的結合會產生多個輸出列,但針對同一個目標表格列,則只會使用其中一個輸出列來更新目標表格。所選取的輸出列是任意的,可能會在 SQLite 的不同版本或不同執行之間變更。

2.2.1. 其他 SQL 資料庫引擎中的 UPDATE FROM

SQL Server 也支援 UPDATE FROM,但在 SQL Server 中,目標表格必須包含在 FROM 子句中。換句話說,目標表格會在陳述式中命名兩次。使用 SQL Server,上述的庫存調整陳述式會寫成如下所示

UPDATE inventory
   SET quantity = quantity - daily.amt
  FROM inventory, 
       (SELECT sum(quantity) AS amt, itemId FROM sales GROUP BY 2) AS daily
 WHERE inventory.itemId = daily.itemId;

MySQL 支援 UPDATE FROM 的概念,但它並非使用 FROM 子句。相反地,完整的聯結規格會出現在 UPDATE 和 SET 關鍵字之間。等效的 MySQL 敘述會像這樣

UPDATE inventory JOIN
       (SELECT sum(quantity) AS amt, itemId FROM sales GROUP BY 2) AS daily
       USING( itemId )
   SET inventory.quantity = inventory.quantity - daily.amt;

MySQL UPDATE 敘述不只有一個目標資料表,這點與其他系統不同。任何參與聯結的資料表都可以在 SET 子句中修改。MySQL UPDATE 語法允許您一次更新多個資料表!

2.3. 選擇性的 LIMIT 和 ORDER BY 子句

如果 SQLite 是使用 SQLITE_ENABLE_UPDATE_DELETE_LIMIT 編譯時間選項所建置,則 UPDATE 敘述的語法會擴充包含選擇性的 ORDER BY 和 LIMIT 子句,如下所示

update-stmt-limited

WITH RECURSIVE common-table-expression , UPDATE OR ROLLBACK qualified-table-name OR REPLACE OR IGNORE OR FAIL OR ABORT SET column-name-list = expr column-name , FROM table-or-subquery , join-clause WHERE expr returning-clause ORDER BY ordering-term , LIMIT expr OFFSET expr , expr

如果 UPDATE 敘述有 LIMIT 子句,則將會更新的最大列數會透過評估隨附的運算式並將其轉換為整數值來找出。負值會被解釋為「沒有限制」。

如果 LIMIT 運算式的評估結果為非負值 N,且 UPDATE 敘述有 ORDER BY 子句,則所有在沒有 LIMIT 子句時會被更新的列會根據 ORDER BY 排序,且前 N 個會被更新。如果 UPDATE 敘述也有 OFFSET 子句,則會以類似的方式評估並轉換為整數值。如果 OFFSET 運算式的評估結果為非負值 M,則會略過前 M 個列,並改為更新後面的 N 個列。

如果 UPDATE 敘述沒有 ORDER BY 子句,則所有在沒有 LIMIT 子句時會被更新的列會在套用 LIMIT 和 OFFSET 子句以決定實際更新哪些列之前,以任意順序組合。

UPDATE 敘述中的 ORDER BY 子句只用於決定哪些列會在 LIMIT 範圍內。列的修改順序是任意的,不受 ORDER BY 子句影響。

此頁面最後修改於 2022-01-08 05:02:57 UTC