【问题标题】:Oracle SQL What is the right syntax to Update a table from a join in a trigger? [duplicate]Oracle SQL 从触发器中的联接更新表的正确语法是什么? [复制]
【发布时间】:2018-03-24 04:05:50
【问题描述】:

我有 3 张桌子:

portees : 表示具有多列的电力线(por_cur、设备 A、设备 B、...、iqu_cur、检查)

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

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

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

有什么想法吗?

【问题讨论】:

  • 您不能使用连接编写更新查询。您需要使用合并
  • 您要更新哪个表?您可以在更新语句的 where 子句中使用规则(可能使用存在),因此您应该只重写选择要更新的行的查询。或者使用合并。
  • 我正在更新表 indice_qualite,我会看看合并。
  • INDICE_QUALITE 甚至是这些表中的列吗?
  • 顺便说一句。 ORA-00904 表示标识符无效,而不是表不存在!您显然是在尝试在 select 语句中选择 TABLE,而不是列。

标签: sql oracle join sql-update database-trigger


【解决方案1】:

您可以这样重写查询:

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 条件中。我不确定这是否可行,因为要求不明确 - 您没有解释任何内容,您只是提供了无效的查询。

【讨论】:

    【解决方案2】:

    试试这个:

    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 上具有唯一索引/约束时,此类更新才有效

    【讨论】:

    • 我尝试了第一个建议,我收到了这个错误:PL/SQL: ORA-00918: Ambigus colomn definition,对于第二个建议(你在第二次加入时出错,它是 JOIN CAB_PORTEES)我收到了这个错误:PL/SQL:ORA-00904:“INDICE_QUALITE”:无效标识符
    • 请立即尝试,您的初始语句有几个错误。没有任何解释,就很难猜出你的意图。
    • @Wernfried Domscheit:我刚刚尝试使用 UNION ALL 进行查询,但它不起作用 - 无论使用 UNION 还是 UNION ALL,我都会得到 ORA-01732。这是在 11.2.0.3 上。
    【解决方案3】:

    您不能使用更新查询编写联接。使用 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;
    

    【讨论】:

    • 您好,感谢您的回答,我尝试了您的建议并遇到了同样的错误。
    • 你能粘贴准确的错误吗
    • PL/SQL: ORA-00904: "INDICE_QUALITE" : 无效标识符
    • INDICE_QUALITE 表中是否有 INDICE_QUALITE 列?
    • 不,我不希望更新的列是来自 INDICE_QUALITE 表的 EXAMINE。
    猜你喜欢
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2020-07-21
    相关资源
    最近更新 更多