从 SQL 数据更改语句检索结果集
使用 INSERT、UPDATE 或 DELETE 语句来修改表的应用程序可能要求对修改的行进行其他处理。要加快此处理,您可以在 SELECT 和 SELECT INTO 语句的 FROM 子句中嵌入 SQL 数据更改操作。
在单一工作单元中,应用程序可以从 SQL 数据更改操作所修改的表或视图中,检索包含所修改行的结果集。
例如,下列语句会更新 SAMPLE 数据库中 EMPLOYEE 表内所有记录的薪水,然后返回所有已更新行的职员编号和新薪水。
SELECT empno, salary FROM FINAL TABLE
(UPDATE employee SET salary = salary * 1.10 WHERE job = 'CLERK')
为了成功返回数据,检索 SQL 数据更改操作的结果集的 SELECT 语句要求 SQL 数据更改操作成功运行。成功执行 SQL 数据更改操作包括成功处理所有约束和触发器(如果适用)。
例如,假设对 EMPLOYEE 表具有 SELECT 特权但不具有 INSERT 特权的用户尝试对 EMPLOYEE 表执行 SELECT FROM INSERT 语句。INSERT 操作会失败,因为缺少特权,并且整个 SELECT 语句会因此而失败。
请考虑下列查询,会在该查询中查询 EMPLOYEE 表的记录,然后将记录插入到另一个表(名为 EMP)中。此 SELECT 语句将失败。
SELECT empno FROM FINAL TABLE
(INSERT INTO emp(name, salary)
SELECT firstnme || midinit || lastname, salary
FROM employee)
如果 EMPLOYEE 表具有 100 行,且第 90 行具有 SALARY 值 $9,999,000.00,那么增加 $10,000.00 会导致发生十进制溢出问题。此溢出会强制数据库管理器回滚对 EMP 表所作的插入。
中间结果表
表或视图(SELECT 语句的 FROM 子句中 SQL 数据更改操作的目标)的已修改行组成中间结果表。除 SQL 数据更改操作中所定义的任何包含列之外,中间结果表还包括目标表或视图的所有列。您可以在查询列表、ORDER BY 子句或 WHERE 子句中按名称引用中间结果表中的所有列。
- OLD TABLE
- 中间结果表中的行将包含目标表行中,时间紧靠前触发器和 SQL 数据更改操作执行之前的值。OLD TABLE 限定词不适用于 UPDATE 和 DELETE 操作。
- NEW TABLE
- 中间结果表中的行将包含目标表行中,时间紧跟 SQL 数据更改语句执行之后,但在引用完整性评估和任何后触发器触发之前的值。NEW TABLE 限定词适用于 UPDATE 和 INSERT 操作。
- FINAL TABLE
- 此限定词返回与 NEW TABLE 相同的中间结果表。此外,使用 FINAL TABLE 可保证任何后触发器或引用完整性约束都不会进一步修改 UPDATE 或 INSERT 操作的目标。FINAL TABLE 限定词适用于 UPDATE 和 INSERT 操作。
FROM 子句限定词确定中间结果表中目标数据的版本。这些限定词不会影响目标表行的插入、删除或更新。
目标表和视图
查询 SQL 数据更改操作的结果集时,目标可以是任一表或视图。
在针对视图执行的 SQL 数据更改操作中,结果表不能包含不再满足 NEW TABLE 和 FINAL TABLE 的视图定义的行。如果您嵌入一个在 SELECT 语句中对视图进行引用的 INSERT 或 UPDATE 语句,那么必须将该视图定义为 WITH CASCADED CHECK OPTION。此外,该视图必须满足可允许您将该视图定义为 WITH CASCADED CHECK OPTION 的限制。
如果在 SELECT 语句的 FROM 子句中嵌入的 SQL 数据更改操作的目标是全查询,那么结果表可以包括全查询中任何不再符合条件的行。这是因为不会根据更新的值对 WHERE 子句中的谓词进行重新求值。
根据 INPUT SEQUENCE 对结果集进行排序
要以行插入至目标表或视图的顺序对行执行 SELECT,请在 ORDER BY 子句中使用 INPUT SEQUENCE 关键字。使用 INPUT SEQUENCE 关键字不会强制以提供行的顺序来插入行。
下列示例演示如何在 ORDER BY 子句中使用 INPUT SEQUENCE 关键字,对 INSERT 操作的结果集进行排序。
CREATE TABLE orders (purchase_date DATE,
sales_person VARCHAR(16),
region VARCHAR(10),
quantity SMALLINT,
order_num INTEGER NOT NULL
GENERATED ALWAYS AS IDENTITY (START WITH 100,
INCREMENT BY 1))
SELECT * FROM FINAL TABLE
(INSERT INTO orders
(purchase_date, sales_person, region, quantity)
VALUES (CURRENT DATE,'Judith','Beijing',6),
(CURRENT DATE,'Marieke','Medway',5),
(CURRENT DATE,'Hanneke','Halifax',5))
ORDER BY INPUT SEQUENCE
PURCHASE_DATE SALES_PERSON REGION QUANTITY ORDER_NUM
------------- ---------------- ---------- -------- -----------
07/18/2003 Judith Beijing 6 100
07/18/2003 Marieke Medway 5 101
07/18/2003 Hanneke Halifax 5 102
您也可以使用包含列对结果集行进行排序。