删除触发器后的PL SQL不插入记录

删除触发器后的PL SQL不插入记录,sql,plsql,triggers,Sql,Plsql,Triggers,我有一个用PL/SQL编写的触发器,用来将删除的记录插入到另一个表中 触发因素如下: CREATE OR REPLACE TRIGGER keepRemoved AFTER DELETE ON schema.table FOR EACH ROW DECLARE selection_id varchar2(10) := NULL; BEGIN /* Check if deleted record already exists in destination table by populati

我有一个用PL/SQL编写的触发器,用来将删除的记录插入到另一个表中

触发因素如下:

CREATE OR REPLACE TRIGGER keepRemoved
AFTER DELETE
ON schema.table
FOR EACH ROW
DECLARE selection_id varchar2(10) := NULL;
BEGIN
    /* Check if deleted record already exists in destination table by populating variable with that value. */
     BEGIN
       SELECT a.primary_key
       INTO selection_id
       FROM [destinationTable] a
       WHERE a.primary_key = :old.removed_key
         AND a.condition_value = true
         AND a.condition_value2 = 42;
       EXCEPTION
         WHEN NO_DATA_FOUND THEN
           selection_id := NULL;
         WHEN OTHERS THEN
           selection_id := NULL;
      END;

    /* If selection_id is null, meaning that value doesn't exist in the destination table, insert deleted record in destination table */
      IF selection_id IS NULL THEN
        INSERT INTO [destinationTable] a
           (a.primary_key,
            a.user_id,
            a.column2,
            ...
            a.columnN)
        VALUES
            (:old.removed_key,
             SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY'),
              123,
              ...
              'MoreText')
       END IF;
       EXCEPTION
         WHEN OTHERS THEN NULL;
 END;
问题是删除记录时,
destinationTable
中没有填充任何内容


在上下文中,我永远不会成为删除记录的用户。

你在这里所说的就像伪代码,而不是真实的代码,所以我帮不了你这么多,但我的建议是:

  • 你有错误吗? 然后按照错误添加调试信息,在dbms_output.put_行中编写一些异常代码来检查它

  • 确保触发器位于执行DML操作的同一个表上

  • 将触发器更改为使用“删除前”

  • 检查目标表中是否存在.primary_键,如果存在,则不会执行插入


  • 您好,请改变一种逻辑,如贝娄使用计数,而不是值和空匹配。此外,计数不需要异常处理

    CREATE OR REPLACE TRIGGER keepRemoved
    AFTER DELETE
    ON schema.table
    FOR EACH ROW
    DECLARE 
    selection_count pls_integer:=0
    BEGIN
        /* Check if deleted record already exists in destination table by populating variable with that value. */
         BEGIN
           SELECT count(*)
           INTO selection_count
           FROM [destinationTable] a
           WHERE a.primary_key = :old.removed_key
             AND a.condition_value = true
             AND a.condition_value2 = 42;
           EXCEPTION     -- can remove this.
             WHEN NO_DATA_FOUND THEN
               selection_count := 0;
             WHEN OTHERS THEN
               selection_count := 1;  
          END;
    
        /* If selection_id is null, meaning that value doesn't exist in the destination table, insert deleted record in destination table */
          IF selection_count = 0 THEN
            INSERT INTO [destinationTable] a
               (a.primary_key,
                a.user_id,
                a.column2,
                ...
                a.columnN)
            VALUES
                (:old.removed_key,
                 SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY'),
                  123,
                  ...
                  'MoreText')
           END IF;
           EXCEPTION
             WHEN OTHERS THEN NULL;
     END; 
    

    代码尽可能接近真实的触发器,而无需在其中输入真实的列名。我没有收到任何错误,触发器存在于同一个模式中,并且在同一个表中,作为DML的执行对象。我会尝试删除前,但从我所读到的我应该能够使用后。和#4已经编码到触发器本身中。尝试在运行时调试触发器并查看是否执行异常,替换null;命令异常,任何检测操作(如insert to test table)都异常。如果记录存在于destinationTable中,但条件_值2为41,该怎么办?您可以将ID设置为null,这意味着您将插入具有相同密钥ID的新记录。如果这是PK,则插入将引发一个您忽略的异常。