UPDATE 的 WHERE 子句中的子查询

UPDATE 语句的 WHERE 子句中的子查询的 FROM 子句可指定与 UPDATE 语句的 Table Options 子句指定的同一表或视图作为数据源。仅当下列条件都为真时,才支持带有引用同一表对象的子查询的 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 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 操作:

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);

要获取更多关于如何使用返回多行作为 UPDATE 语句的 WHERE 子句中的断言的信息,请参阅 带有子查询的条件 主题。