在出现应用程序错误但回滚后尝试插入表

Posted

技术标签:

【中文标题】在出现应用程序错误但回滚后尝试插入表【英文标题】:Trying to insert into table after rising the application error but its rollbacks 【发布时间】:2022-01-01 22:22:03 【问题描述】:

我正在尝试创建一个触发器来限制用户在周六和周日执行 DDL,但如果有人尝试插入数据,它会将数据保存在 weekend_action 表中,但也会引发无法执行 DDL 的应用程序错误。

SQL 查询:

create or replace trigger tgr_wkd_action
before insert
on tbl_39_dept_k 
for each row
declare
begin
  IF trim(TO_CHAR(sysdate,'Day')) IN ('Tuesday', 'Sunday') then 
     RAISE_APPLICATION_ERROR (-20000,'you cannot perform DDL on Weekend');
  end if;
  
  if inserting then
     insert into user_admin.weekend_actions values 
       (:NEW.Dept_no,
        'updation',
        'user'||user||'trying to insert data on'||'_'||sysdate||'from Table tbl_39_dept_k');
  end if;
end tgr_wkd_action;

【问题讨论】:

您的代码是IF tue/sun THEN raise error ELSE log error。这是你想要的吗?或者您只想在周二/周日而不是周二/周日写日志条目?或者甚至不分白天?请记住RAISE_APPLICATION_ERROR 退出脚本;一旦你提出一个错误,你将不会看到后面的每一行。 不不,我只是说因为我正在检查它......今天是星期二这就是为什么 我想提出应用程序错误并获取日志条目 然后将插入语句移到 raise 语句之前。 即使我在 raise 语句之前移动它也不会起作用,因为 raise 语句会回滚 【参考方案1】:

如果有人试图插入数据

没错。插入。

您的触发器在 update 之前触发,这是一个不同的 DML。


除此之外:

插入和更新是 DML(数据操作)。您提到的 DDL 是数据定义(这些是创建表、更改表...) 周末活动与星期二?从星期二开始周末

也许你的意思

SQL> CREATE OR REPLACE TRIGGER tgr_wkd_action
  2     BEFORE INSERT OR UPDATE
  3     ON tbl_39_dept_k
  4     FOR EACH ROW
  5  DECLARE
  6  BEGIN
  7     IF TRIM (TO_CHAR (SYSDATE, 'Day', 'nls_date_language = english')) IN
  8           ('Saturday', 'Sunday')
  9     THEN
 10        RAISE_APPLICATION_ERROR (-20000, 'you cannot perform DML on Weekend');
 11     END IF;
 12
 13     IF INSERTING
 14     THEN
 15        INSERT INTO weekend_actions
 16                VALUES (
 17                          :NEW.Dept_no,
 18                          'inserting',
 19                             'user'
 20                          || USER
 21                          || 'trying to insert data on'
 22                          || '_'
 23                          || SYSDATE
 24                          || 'from Table tbl_39_dept_k');
 25     ELSIF UPDATING
 26     THEN
 27        INSERT INTO weekend_actions
 28                VALUES (
 29                          :NEW.Dept_no,
 30                          'updating',
 31                             'user'
 32                          || USER
 33                          || 'trying to update data on'
 34                          || '_'
 35                          || SYSDATE
 36                          || 'from Table tbl_39_dept_k');
 37     END IF;
 38  END tgr_wkd_action;
 39  /

Trigger created.

SQL>
SQL> INSERT INTO tbl_39_dept_k (dept_no) VALUES (10);

1 row created.

SQL>

表格内容:

SQL> select * from tbl_39_dept_k;

   DEPT_NO
----------
        10

SQL> select * from weekend_actions;

   DEPT_NO ACTION     MSG
---------- ---------- ----------------------------------------------------------------------
        10 inserting  userSCOTTtrying to insert data on_23.11.21from Table tbl_39_dept_k

SQL>

假装今天是周末(虽然是星期二):

<snip>
  7     IF TRIM (TO_CHAR (SYSDATE, 'Day', 'nls_date_language = english')) IN
  8           ('Tuesday', 'Sunday')
  9     THEN
<snip>
 39  /

Trigger created.

SQL>
SQL> INSERT INTO tbl_39_dept_k (dept_no) VALUES (20);
INSERT INTO tbl_39_dept_k (dept_no) VALUES (20)
            *
ERROR at line 1:
ORA-20000: you cannot perform DML on Weekend
ORA-06512: at "SCOTT.TGR_WKD_ACTION", line 6
ORA-04088: error during execution of trigger 'SCOTT.TGR_WKD_ACTION'


SQL>

【讨论】:

是只会报错还是插入到日志表中 你的代码没问题,但我仍然遇到同样的问题,它引发了错误,但它没有在日志表中插入值 对;我的代码没问题。我建议你调整你的代码,让它和我的一样工作。 没有你的代码是好的,但它没有做我的问题是..实际上,我的代码也可以正常工作......我希望触发器同时显示异常和插入星期六的时间......你的代码剂量它只显示异常但不插入 您不能引发异常并让行被插入。如果引发异常,仅此而已 - 不允许进一步处理(因此,永远不会发生插入)。

以上是关于在出现应用程序错误但回滚后尝试插入表的主要内容,如果未能解决你的问题,请参考以下文章

休眠:java.sql.SQLException:事务回滚后尝试继续工作

sql try/catch rollback/commit - 防止回滚后的错误提交

在 TFS 2013 中启动回滚后,我可以恢复我最近的本地更改吗?

MySQL事务回滚后自增键不连续

在集成测试中每个方法不回滚后 Spring Data JPA 数据库更改

Spring Kafka - 事务回滚后重试时,通过侦听器容器事务发布消息和提交记录偏移失败