一 、概述
返回子句:
隐藏
RETURNING
expr
AS
column-alias
*
,
表达式:
节目
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
DISTINCT
expr
)
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
过滤器子句:
节目
字面值:
节目
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
过度条款:
节目
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
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
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
提升功能:
节目
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
选择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
公用表表达式:
节目
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
复合运算符:
节目
UNION
UNION
INTERSECT
EXCEPT
ALL
加入子句:
节目
table-or-subquery
join-operator
table-or-subquery
join-constraint
加入约束:
节目
USING
(
column-name
)
,
ON
expr
联合运营商:
节目
NATURAL
LEFT
OUTER
JOIN
,
RIGHT
FULL
INNER
CROSS
订购条款:
节目
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
结果列:
节目
expr
AS
column-alias
*
table-name
.
*
表或子查询:
节目
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
窗口定义:
节目
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
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
类型名称:
节目
name
(
signed-number
,
signed-number
)
(
signed-number
)
签名号码:
节目
RETURNING 子句本身不是语句,而是一个可以选择出现在顶级
DELETE 、 INSERT 和 UPDATE 语句末尾附近的子句。 RETURNING 子句的作用是使语句为删除、插入或更新的每个数据库行返回一个结果行。 RETURNING 不是标准 SQL。 它是一个扩展。 SQLite 的 RETURNING 语法仿照
PostgreSQL 建模。
SQLite 从 3.35.0 (2021-03-12) 版本开始支持 RETURNING 语法。
1.1. 典型用途
RETURNING 子句旨在为应用程序提供由 SQLite 自动填充的列的值。 例如:
CREATE TABLE t0(
a INTEGER PRIMARY KEY,
b DATE DEFAULT CURRENT_TIMESTAMP,
c INTEGER
);
INSERT INTO t0(c) VALUES(random()) RETURNING *;
在上面的 INSERT 语句中,SQLite 计算所有三列的值。 RETURNING 子句使 SQLite 将选择的值报告回应用程序。 这使应用程序不必发出单独的查询来准确找出插入的值。
2. 细节
RETURNING 子句后跟以逗号分隔的表达式列表。 这些表达式类似于 SELECT 语句 中 SELECT 关键字后面的表达式,因为它们定义了结果集中列的值。 每个表达式定义单个列的值。 每个表达式后面都可以有选择地跟一个 AS 子句,它确定结果列的名称。 特殊的“*”表达式扩展为 正在删除、插入或更新的表
的所有 非隐藏列的列表。
对于 INSERT 和 UPDATE 语句,对正在修改的表中的列的引用是指应用更改 后 该列的值。 对于 DELETE 语句,对列的引用表示 删除发生
之前的值。
RETURNING 子句仅返回由 DELETE、INSERT 或 UPDATE 语句直接修改的行。 RETURNING 子句不报告由 外键约束 或 触发器 引起的任何其他数据库更改。
UPSERT
的 RETURNING 子句 报告插入的行和更新的行。
2.1. 加工订单
当运行带有 RETURNING 子句的 DELETE、INSERT 或 UPDATE 语句时,所有数据库更改都发生在第一次调用 sqlite3_step() 期间。 RETURNING 子句的输出在内存中累积。 第一个 sqlite3_step() 调用返回一行 RETURNING 输出,随后的 RETURNING 输出行由对 sqlite3_step() 的后续调用返回。 换句话说,在所有数据库修改操作完成之前,所有 RETURNING 子句输出都将被禁止。
这意味着,如果语句具有生成大量输出的 RETURNING 子句,无论是多行还是大字符串或 BLOB 值,那么该语句在运行时可能会使用大量临时内存来保存这些值。
RETURNING 子句的第一个原型返回生成的值。 这种方法使用的内存较少,但它还有其他问题:
如果为两个或多个交错的 DML 语句调用 sqlite3_step(),并且如果其中一个语句遇到约束失败并中止,恢复其更改,那么这可能会中断另一个 DML 语句的操作。 这不会破坏数据库文件,但会在数据库中产生令人惊讶且难以解释的结果。
如果应用程序在收到 SQLITE_DONE 之前未能重复调用 sqlite3_step(),那么某些数据库更改可能永远不会发生。
操作顺序与 PostgreSQL 等客户端/服务器数据库引擎不同,这可能会导致某些应用程序出现可移植性问题。
由于这些原因,修改了当前的实现,以便在发出任何 RETURNING 输出之前发生所有数据库更改。
虽然 SQLite 确实保证所有数据库更改都将在发出任何 RETURNING 输出之前发生,但它 不 保证各个 RETURNING 行的顺序与数据库中这些行的更改顺序相匹配。 RETURNING 行的输出顺序是任意的,不一定与内部处理行的顺序相关。
3. 限制和注意事项
RETURNING 子句在针对虚拟表
的 DELETE 和 UPDATE 语句中不可用 。 在 SQLite 的未来版本中可能会删除此限制。
RETURNING 子句仅在顶级 DELETE、INSERT 和 UPDATE 语句中可用。 触发器中的语句不能使用 RETURNING 子句。
即使带有 RETURNING 子句的 DML 语句返回表内容,它也不能用作子查询。 RETURNING 子句只能将数据返回给应用程序。 目前无法将 RETURNING 输出转移到另一个表或查询中。 PostgreSQL 能够使用带有 RETURNING 子句的 DML 语句,就像
普通表表达式 中的视图一样。 SQLite 目前不具备这种能力,尽管这可能会在未来的版本中添加。
RETURNING 子句发出的行以任意顺序出现。 该顺序可能会根据数据库模式、所使用的 SQLite 的特定版本、甚至从同一语句的一次执行到下一次执行而改变。 无法使输出行以特定顺序出现。 即使使用 SQLITE_ENABLE_UPDATE_DELETE_LIMIT
选项编译 SQLite,以便在 DELETE 和 UPDATE 语句中允许使用 ORDER BY 子句,这些 ORDER BY 子句不会限制 RETURNING 的输出顺序。
RETURNING 子句发出的值是顶级 DELETE、INSERT 或 UPDATE 语句所见的值,不反映 触发器 所做的任何后续值更改。 因此,如果数据库包含修改插入或更新的每一行的某些值的 AFTER 触发器,则 RETURNING 子句发出在这些触发器运行之前计算的原始值。
RETURNING 子句可能不包含顶级 聚合函数 或
窗口函数 。 如果 RETURNING 子句中有子查询,那些子查询可能包含聚合和窗口函数,但聚合不能出现在顶层。
RETURNING 子句只能引用被修改的表。 在 UPDATE FROM 语句中,FROM 子句中命名的辅助表可能不参与 RETURNING 子句。