即使触发器失败,如何将数据插入 table?

How to insert data into table even if trigger fails?

甲骨文 11.1

我有自定义日志记录 table,我在其中插入数据:

CREATE TABLE log_table
(
    message      VARCHAR2(255),
    created_by   VARCHAR2(40) NOT NULL,
    created_at   DATE         NOT NULL,
);

我有一个在特定 table 上运行的触发器,它会进行一些检查。我的问题是:当触发器失败时,我希望能够将一些数据记录到 log_table.

触发器:

CREATE OR REPLACE TRIGGER my_trigger
    FOR INSERT OR UPDATE OF column
    ON my_table
    COMPOUND TRIGGER

BEFORE STATEMENT IS
BEGIN
   // code
END BEFORE STATEMENT;

    BEFORE EACH ROW IS
    BEGIN
        IF (/*condition for failing*/) THEN
            EXECUTE IMMEDIATE 'INSERT INTO mesaj_ama VALUES (:my_message, :my_user, :my_data)'
                USING 'custom error message', SYS.LOGIN_USER, SYSDATE;
            RAISE_APPLICATION_ERROR(-20001, 'some error');
        END IF;
    END BEFORE EACH ROW;
    END my_trigger;
/

以下代码无效。我尝试使用 EXECUTE IMMEDIATE 来强制它,但没有用。我知道如果出现错误,会自动进行 table 回滚(这意味着 INSERT 命令被取消),但我需要一种方法来执行此操作。有帮助吗?

您要查找的概念是 Autonomous Trasnaction,例如

CREATE OR REPLACE TRIGGER log_sal
  BEFORE UPDATE OF salary ON emp FOR EACH ROW
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO log (
    log_id,
    up_date,
    new_sal,
    old_sal
  )
  VALUES (
    :old.employee_id,
    SYSDATE,
    :new.salary,
    :old.salary
  );
  COMMIT;
END;

是的,PRAGMA AUTONOMOUS_TRANSACTION 似乎就是答案。这是工作代码:

定义了一个记录过程:

CREATE OR REPLACE PROCEDURE log_error(p_error log_table.message % TYPE) AS
    PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    INSERT INTO log_table
    VALUES (p_error, SYS.LOGIN_USER, SYSDATE);
    COMMIT;
END;

和调用过程的触发器:

CREATE OR REPLACE TRIGGER my_trigger
    FOR INSERT OR UPDATE OF column
    ON my_table
    COMPOUND TRIGGER

BEFORE STATEMENT IS
BEGIN
   // code
END BEFORE STATEMENT;

    BEFORE EACH ROW IS
    BEGIN
        IF (/*condition for failing*/) THEN

           log_error('custom error message');
           RAISE_APPLICATION_ERROR(-20001, 'custom error message');

        END IF;
    END BEFORE EACH ROW;
    END my_trigger;
/