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
显示
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
select-stmt
显示
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
显示
UNION
UNION
INTERSECT
EXCEPT
ALL
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column
显示
expr
AS
column-alias
*
table-name
.
*
window-defn
显示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
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
显示
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
显示
function-arguments
显示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
literal-value
显示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause
显示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
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
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
raise-function
显示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
select-stmt
显示
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
显示
UNION
UNION
INTERSECT
EXCEPT
ALL
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column
显示
expr
AS
column-alias
*
table-name
.
*
window-defn
显示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
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
显示
name
(
signed-number
,
signed-number
)
(
signed-number
)
signed-number
显示
join-clause
显示
table-or-subquery
join-operator
table-or-subquery
join-constraint
join-constraint
显示
USING
(
column-name
)
,
ON
expr
join-operator
显示
NATURAL
LEFT
OUTER
JOIN
,
RIGHT
FULL
INNER
CROSS
qualified-table-name
显示
schema-name
.
table-name
AS
alias
INDEXED
BY
index-name
NOT
INDEXED
returning-clause
显示
RETURNING
expr
AS
column-alias
*
,
table-or-subquery
显示
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
显示
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
显示
UNION
UNION
INTERSECT
EXCEPT
ALL
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column
显示
expr
AS
column-alias
*
table-name
.
*
window-defn
显示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
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 语句一部分指定的 qualified-table-name 标识。
2. 详细
如果 UPDATE 语句没有 WHERE 子句,则表中的所有行都会被 UPDATE 修改。否则,UPDATE 仅影响 WHERE 子句 布尔表达式为真 的那些行。如果 WHERE 子句对表中的任何行都不计算为真,这不是错误 - 这仅仅意味着 UPDATE 语句影响零行。
UPDATE 语句影响的每一行所做的修改由 SET 关键字后跟的一系列赋值决定。每个赋值在等号左侧指定一个 column-name ,在右侧指定一个标量表达式。对于每个受影响的行,命名列设置为通过计算相应的标量表达式找到的值。如果单个 column-name 在赋值表达式列表中出现多次,则除了最右边的出现之外,所有其他出现都被忽略。未出现在赋值列表中的列保持不变。标量表达式可以引用正在更新的行中的列。在这种情况下,所有标量表达式都在进行任何赋值之前计算。
从 SQLite 3.15.0 版 (2016-10-14)开始,SET 子句中的赋值可以在左侧是 带括号的列名列表 ,在右侧是相同大小的 行值 。
在 UPDATE 关键字后跟随的可选“OR action ”冲突子句允许用户指定在此单个 UPDATE 命令期间使用的特定约束冲突解决算法。有关更多信息,请参阅标题为 ON CONFLICT 的部分。
2.1. CREATE TRIGGER 内 UPDATE 语句的限制
以下其他语法限制适用于出现在 CREATE TRIGGER 语句主体内的 UPDATE 语句。
作为触发器主体中 UPDATE 语句一部分指定的 table-name 必须是未限定的。换句话说,UPDATE 的表名上的schema-name . 前缀在触发器中是不允许的。除非附加触发器的表位于 TEMP 数据库中,否则触发器程序更新的表必须与它位于同一数据库中。如果附加触发器的表位于 TEMP 数据库中,则更新表的未限定名称将以与顶级语句相同的方式解析(首先搜索 TEMP 数据库,然后搜索主数据库,然后搜索按附加顺序排列的任何其他数据库)。
INDEXED BY 和 NOT INDEXED 子句在触发器内的 UPDATE 语句中是不允许的。
无论用于构建 SQLite 的编译选项如何,触发器内都不支持 UPDATE 的 LIMIT 和 ORDER BY 子句。
2.2. UPDATE FROM
UPDATE-FROM 思想是对 SQL 的扩展,它允许 UPDATE 语句由数据库中的其他表驱动。“目标”表是正在更新的特定表。使用 UPDATE-FROM,您可以将目标表与数据库中的其他表连接起来,以帮助计算需要更新的行以及这些行上的新值应该是什么。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 会根据当天的汇总销售额调整数量。语句将如下所示
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 和 OFFSET 子句以确定实际更新的行之前,将所有在没有 LIMIT 子句的情况下将更新的行以任意顺序组合在一起。
UPDATE 语句上的 ORDER BY 子句仅用于确定哪些行属于 LIMIT 范围内。修改行的顺序是任意的,不受 ORDER BY 子句的影响。
此页面上次修改于 2022-01-08 05:02:57 UTC