即使触发器失败,如何将数据插入 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;
/
甲骨文 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;
/