回归

、概述

返回子句:

RETURNING expr AS column-alias * ,

表达式:

RETURNING 子句本身不是语句,而是一个可以选择出现在顶级 DELETEINSERTUPDATE语句末尾附近的子句。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 子句的第一个原型返回生成的值。这种方法使用的内存较少,但它还有其他问题:

  1. 如果为两个或多个交错的 DML 语句调用 sqlite3_step(),并且如果其中一个语句遇到约束失败并中止,恢复其更改,那么这可能会中断另一个 DML 语句的操作。这不会破坏数据库文件,但会在数据库中产生令人惊讶且难以解释的结果。

  2. 如果应用程序在收到 SQLITE_DONE 之前未能重复调用 sqlite3_step(),那么某些数据库更改可能永远不会发生。

  3. 操作顺序与 PostgreSQL 等客户端/服务器数据库引擎不同,这可能会导致某些应用程序出现可移植性问题。

由于这些原因,修改了当前的实现,以便在发出任何 RETURNING 输出之前发生所有数据库更改。

虽然 SQLite 确实保证所有数据库更改都将在发出任何 RETURNING 输出之前发生,但它保证各个 RETURNING 行的顺序与数据库中这些行的更改顺序相匹配。RETURNING 行的输出顺序是任意的,不一定与内部处理行的顺序相关。

3.限制和注意事项

  1. RETURNING 子句在针对虚拟表 的 DELETE 和 UPDATE 语句中不可用在 SQLite 的未来版本中可能会删除此限制。

  2. RETURNING 子句仅在顶级 DELETE、INSERT 和 UPDATE 语句中可用。触发器中的语句不能使用 RETURNING 子句。

  3. 即使带有 RETURNING 子句的 DML 语句返回表内容,它也不能用作子查询。RETURNING 子句只能将数据返回给应用程序。目前无法将 RETURNING 输出转移到另一个表或查询中。PostgreSQL 能够使用带有 RETURNING 子句的 DML 语句,就像 普通表表达式中的视图一样。SQLite 目前不具备这种能力,尽管这可能会在未来的版本中添加。

  4. RETURNING 子句发出的行以任意顺序出现。该顺序可能会根据数据库模式、所使用的 SQLite 的特定版本、甚至从同一语句的一次执行到下一次执行而改变。无法使输出行以特定顺序出现。即使使用SQLITE_ENABLE_UPDATE_DELETE_LIMIT 选项编译 SQLite,以便在 DELETE 和 UPDATE 语句中允许使用 ORDER BY 子句,这些 ORDER BY 子句不会限制 RETURNING 的输出顺序。

  5. RETURNING 子句发出的值是顶级 DELETE、INSERT 或 UPDATE 语句所见的值,不反映触发器所做的任何后续值更改。因此,如果数据库包含修改插入或更新的每一行的某些值的 AFTER 触发器,则 RETURNING 子句发出在这些触发器运行之前计算的原始值。

  6. RETURNING 子句可能不包含顶级聚合函数窗口函数如果 RETURNING 子句中有子查询,那些子查询可能包含聚合和窗口函数,但聚合不能出现在顶层。

  7. RETURNING 子句只能引用被修改的表。UPDATE FROM语句中,FROM 子句中命名的辅助表可能不参与 RETURNING 子句。