1. 概觀
update-stmt
hide
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
show
common-table-expression
show
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
select-stmt
show
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator
show
UNION
UNION
INTERSECT
EXCEPT
ALL
ordering-term
show
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column
show
expr
AS
column-alias
*
table-name
.
*
window-defn
show
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
show
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
expr
show
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause
show
function-arguments
show
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
ordering-term
show
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
literal-value
show
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause
show
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
show
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
ordering-term
show
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
raise-function
show
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
select-stmt
show
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator
show
UNION
UNION
INTERSECT
EXCEPT
ALL
ordering-term
show
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column
show
expr
AS
column-alias
*
table-name
.
*
window-defn
show
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
show
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
type-name
show
name
(
signed-number
,
signed-number
)
(
signed-number
)
signed-number
show
join-clause
show
table-or-subquery
join-operator
table-or-subquery
join-constraint
join-constraint
show
USING
(
column-name
)
,
ON
expr
join-operator
show
NATURAL
LEFT
OUTER
JOIN
,
RIGHT
FULL
INNER
CROSS
qualified-table-name
show
schema-name
.
table-name
AS
alias
INDEXED
BY
index-name
NOT
INDEXED
returning-clause
show
RETURNING
expr
AS
column-alias
*
,
table-or-subquery
show
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
select-stmt
show
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator
show
UNION
UNION
INTERSECT
EXCEPT
ALL
ordering-term
show
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column
show
expr
AS
column-alias
*
table-name
.
*
window-defn
show
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
show
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
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 陳述式。
在觸發器主體中作為 UPDATE 陳述式一部分指定的 table-name 必須是不限定的。換句話說,UPDATE 中 table name 上的 schema-name . 前綴在觸發器中是不允許的。除非附加觸發器的 table 在 TEMP 資料庫中,否則觸發器程式更新的 table 必須與其駐留在同一個資料庫中。如果附加觸發器的 table 在 TEMP 資料庫中,則更新的 table 的不限定名稱會以與頂層陳述式相同的方式解析(先搜尋 TEMP 資料庫,然後是主資料庫,然後是其他資料庫,依附加順序)。
觸發器中的 UPDATE 陳述式不允許使用 INDEXED BY 和 NOT INDEXED 子句。
無論用於建置 SQLite 的編譯選項為何,觸發器中 UPDATE 的 LIMIT 和 ORDER BY 子句都不受支援。
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