UPDATE 的 WHERE 子句
WHERE 子句让您指定搜索标准来限制要被更新的行。如果您省略 WHERE 子句,则更新表中的每行。要获取更多信息,请参阅 SELECT 的 WHERE 子句。
当更新符合 ANSI 的数据库时的 SQLSTATE 值
如果您在符合 ANSI 的数据库中以 UPDATE 语句更新表,其中包含 WHERE 子句且未找到行,则数据库服务器发出警告。
您可以下列方式之一检测此警告条件:
- GET DIAGNOSTICS 语句将 RETURNED_SQLSTATE 字段设置为值 02000。 在 SQL API 应用中,SQLSTATE 变量包含与此相同的值。
- 在 SQL API 应用中,sqlca.sqlcode 和 SQLCODE 变量包含值 100。
数据库服务器还将 SQLSTATE 和 SQLCODE 设置为这些值,如果 UPDATE ... WHERE 语句是多语句 PREPARE 的一部分且数据库服务器不返回行的话。
当更新非 ANSI 数据库时的 SQLSTATE 的值
在不符合 ANSI 的数据库中,当数据库服务器发现没有与 UPDATE 语句的 WHERE 子句相匹配的行时,它不返回警告。SQLSTATE 代码为 00000 且 SQLCODE 代码为零(0)。然而,如果 UPDATE ... WHERE 语句是多语句 PREPARE 的一部分,且未返回行,则数据库服务器发出警告,并设置 SQLSTATE 为 02000,设置 SQLCODE 为 100。
GBase 8s 的客户端-服服务器通信协议,诸如 SQLI 和 DRDA®,支持 SQLSTATE 代码值。要了解这些代码的列表,以及要了解关于如何获得该消息文本的信息,请参阅 使用 SQLSTATE 错误状态代码。
UPDATE 的 WHERE 子句中的子查询
UPDATE 语句的 WHERE 子句中的子查询的 FROM 子句可指定与 UPDATE 语句的 Table Options 子句指定的同一表或视图作为数据源。仅当下列条件都为真时,才支持带有引用同一表对象的子查询的 UPDATE 操作:
- 该子查询或者返回单个行,或者有不相关的列引用。
- 该子查询在 UPDATE 语句 WHERE 子句中,以 Subquery 语法使用 Condition。
- 在该子查询中没有 SPL 例程可引用 UPDATE 正在修改的同一表。
除非满足所有这些条件,否则包括引用 UPDATE 语句修改的同一表或视图的子查询的 UPDATE 语句返回错误 -360。
下列示例通过将更新 unit_price 值减去价格子集的 5% 来更新 stock 表。 WHERE 子句通过将 IN 运算符应用于由子查询返回的行来指定减去哪个价格,仅选择 unit_price 值大于 50 的 stock 表的行:
UPDATE stock SET unit_price = unit_price * 0.95
WHERE unit_price IN
(SELECT unit_price FROM stock WHERE unit_price > 50);
此子查询仅包括不相关的列引用,因为它的唯一的引用的列是在它的 FROM 子句指定的表中。以上罗列的要求生效,因为该子查询的数据源与外部的 UPDATE 语句的 Table Options 子句指定的是相同的 stock 表。
前面的示例与发出两个单独的 DML 语句产生相同的结果:
- SELECT 语句,从 stock 表返回临时表,tmp1 包含的行与子查询返回的行相同。
- UPDATE 语句,发出临时表的子查询作为在它的 WHERE 子句中的断言来修改其 unit_price 与临时表中的执行匹配的 stock 表的每一行:
SELECT unit_price FROM stock WHERE unit_price > 50 INTO TEMP tmp1;
UPDATE stock SET unit_price = unit_price * 0.95
WHERE unit_price IN ( SELECT * FROM tmp1 );
这里是一个在它的 WHERE 子句中包括多个不相关的子查询的更复杂的 UPDATE 语句的示例:
UPDATE t1 SET a = a + 10
WHERE a > ALL (SELECT a FROM t1 WHERE a > 1) AND
a > ANY (SELECT a FROM t1 WHERE a > 10) AND
EXISTS (SELECT a FROM t1 WHERE a > 5);;
如果在表上定义启用的 Select 触发器,该表是修改同一表的 UPDATE 语句的 WHERE 子句中的子查询的数据源,则在该 UPDATE 语句之内执行那个子查询不激活该 Select 触发器。请考虑下列程序片断:
CREATE TRIGGER selt11 SELECT ON t1 BEFORE
(UPDATE d1
SET (c1, c2, c3, c4, c5) =
(c1 + 1, c2 + 1, c3 + 1, c4 + 1, c5 + 1));
UPDATE t2 SET c1 = c1 +1
WHERE c1 IN
(SELECT t1.c1 from t1 WHERE t1.c1 > 10 );
在上述示例中,不作为 t2 上 UPDATE 操作的一部分激活表触发器 selt11。
UPDATE 语句的 WHERE 子句中的子查询可包括 UNION 或 UNION ALL 运算符,如下例所示。
UPDATE t1 SET a = a + 10 WHERE a in (SELECT a FROM t1 WHERE a > 1
UNION SELECT a FROM t1, t2 WHERE a < b);
如果外部的 UPDATE 语句修改的表是表层级之内的类型表,则 GBase 8s 支持使用 UPDATE 的 WHERE 子句中有效子查询的所有下列操作:
- UPDATE 在目标父表上以子查询(SELECT from parent table)
- UPDATE 在目标父表上以子查询(SELECT from child table)
- UPDATE 在目标孩子表上以子查询(SELECT from parent table)
- UPDATE 在目标孩子表上以子查询(SELECT from child table)。
下列程序片断说明以类型表上的子查询的 UPDATE 操作:
CREATE ROW TYPE r1 (c1 INT, c2 INT);
CREATE ROW TYPE r2 UNDER r1;
CREATE TABLE t1 OF TYPE r1; -- parent table
CREATE TABLE t2 OF TYPE r2 UNDER t1; -- child table
UPDATE t1 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t1.c1 FROM t1 WHERE t1.c1 > 10);
UPDATE t1 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t2.c1 FROM t2 WHERE t2.c1 > 10);
UPDATE t2 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t2.c1 FROM t2 WHERE t2.c1 > 10);
UPDATE t2 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t1.c1 FROM t1 WHERE t1.c1 > 10);
要获取更多关于如何使用返回多行作为 UPD