Oracle SQL 从触发器中的连接更新 table 的正确语法是什么?

Oracle SQL What is the right syntax to Update a table from a join in a trigger?

我有 3 tables :

portees : 代表一条有几列的电线 (por_cur, 设备 A, 设备 B, ..., iqu_cur, 检查)

cab_portees : 表示线路上的特定设备(一条线路上可以有多个这些设备的实例), 列 (id, por_cur (来自 portees 的外键), ..., iqu_cur)

indice_qualite :表示其他两个 table 之一的 1 个属性,被认为是重要数据。列(table_name、attribut_name、...、iqu_cur、检查)

我们检查 table portees 和 cab_portees 中的数据以确保其正确,当检查一行时我们将 portees.examine 更新为“1”。我想触发自动更新 table indice_qualite :将 table 中的所有设备放入 examine = '1'.

我无法获得正确的语法,这是我的语法:

    create or replace trigger PORTEES_EXAMINE_TRIGGER
    AFTER UPDATE ON PORTEES
    FOR EACH ROW

    BEGIN

    if :new.EXAMINE != :old.EXAMINE then

   UPDATE (SELECT INDICE_QUALITE.EXAMINE FROM 
          INDICE_QUALITE, PORTEES
          WHERE PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
          AND PORTEES.IQU_CUR = :old.IQU_CUR
          UNION
          SELECT INDICE_QUALITE.EXAMINE FROM 
          INDICE_QUALITE, CAB_PORTEES
          WHERE CAB_PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
          AND CAB_PORTEES.POR_CUR = :old.POR_CUR)

    SET INDICE_QUALITE.EXAMINE = :new.EXAMINE;

    end if;

    END PORTEES_EXAMINE_TRIGGER;

有什么想法吗?

你不能写连接更新查询。使用 Merge 进行连接。

MERGE INTO INDICE_QUALITE M USING
  (SELECT EXAMINE,
   INDICE_QUALITE.IQU_CUR
   FROM INDICE_QUALITE,
        PORTEES
   WHERE PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
     AND PORTEES.IQU_CUR = :old.IQU_CUR
   UNION 
   SELECT EXAMINE,
   INDICE_QUALITE.IQU_CUR
   FROM INDICE_QUALITE,
        CAB_PORTEES
   WHERE CAB_PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
     AND CAB_PORTEES.POR_CUR = :old.POR_CUR) T ON (M.IQU_CUR = T.IQU_CUR) WHEN MATCHED THEN
UPDATE
SET EXAMINE = :new.EXAMINE;

试试这个:

UPDATE (SELECT INDICE_QUALITE.EXAMINE  FROM 
      INDICE_QUALITE, PORTEES
      WHERE PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
      AND PORTEES.IQU_CUR = :old.IQU_CUR
      UNION ALL
      SELECT INDICE_QUALITE.EXAMINE FROM 
      INDICE_QUALITE, CAB_PORTEES
      WHERE CAB_PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
      AND CAB_PORTEES.POR_CUR = :old.POR_CUR) t
SET t.EXAMINE = :new.EXAMINE;

但是,我不知道这是否适用于 UNION ALL(当然它不适用于 UNION)。此外,您应该更喜欢 ANSI 连接语法而不是旧的 Oracle 连接语法。

否则尝试:

UPDATE (SELECT INDICE_QUALITE.EXAMINE  
        FROM INDICE_QUALITE
           JOIN CAB_PORTEES ON CAB_PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
      WHERE PORTEES.IQU_CUR = :old.IQU_CUR) t
SET t.EXAMINE = :new.EXAMINE;

UPDATE (SELECT INDICE_QUALITE.EXAMINE  
        FROM INDICE_QUALITE
           JOIN PORTEES ON CAB_PORTEES.IQU_CUR = INDICE_QUALITE.IQU_CUR
      WHERE CAB_PORTEES.POR_CUR = :old.POR_CUR) t
SET t.EXAMINE = :new.EXAMINE;

请注意,仅当您在 CAB_PORTEES.IQU_CURINDICE_QUALITE.IQU_CUR

上具有 UNIQUE index/constraint 时,此类更新才有效

您可以这样重写查询:

UPDATE INDICE_QUALITE iq
   SET iq.EXAMINE = :new.EXAMINE
 WHERE EXISTS (SELECT 1
                 FROM PORTEES p
                WHERE p.IQU_CUR = iq.IQU_CUR
                  AND p.IQU_CUR = :old.IQU_CUR
                UNION ALL
               SELECT 1
                 FROM CAB_PORTEES cp
                WHERE cp.IQU_CUR = iq.IQU_CUR
                  AND cp.POR_CUR = :old.POR_CUR);

我已将所有规则放在更新语句的 exists 条件中。我不确定这是否可行,因为要求不明确 - 您没有解释任何内容,您只是提供了无效的查询。