触发和约束违规中的autonomous_transaction

发布于 2024-12-05 02:31:02 字数 953 浏览 2 评论 0原文

我在尝试autonomous_transaction时遇到了一个有趣的情况。考虑以下情况(请注意,它不打算这样写:只是概念证明):

create table t
(
id int primary key,
changed date
)
/

create or replace trigger t_trig
before insert or update
on t
for each row
declare
  PRAGMA AUTONOMOUS_TRANSACTION;
begin
  :new.changed := sysdate;
  commit;
end;
/

insert into t(id, changed) values (1, sysdate);
insert into t(id, changed) values (2, sysdate);

截至当前时间的更改日期:

SQL> select * from t;

       ID CHANGED
--------- -----------------
        1 19.09.11 15:29:44
        2 19.09.11 15:32:35

让我们休息 5 秒,然后执行以下操作:

 update t set id = 2 where id = 1;

显然,它会因违反约束而失败,但它也不会更改 changed 属性:

SQL> select * from t;

       ID CHANGED
--------- -----------------
        1 19.09.11 15:29:44
        2 19.09.11 15:32:35

我的问题是:为什么会发生这种情况?我确信我误解了一些基本概念,但我不明白。

预先感谢您的帮助。

I've encountered an interesting situation experimenting with the autonomous_transaction. Consider the following situation (please note it's is not intended to be written this way: just proof of concept):

create table t
(
id int primary key,
changed date
)
/

create or replace trigger t_trig
before insert or update
on t
for each row
declare
  PRAGMA AUTONOMOUS_TRANSACTION;
begin
  :new.changed := sysdate;
  commit;
end;
/

insert into t(id, changed) values (1, sysdate);
insert into t(id, changed) values (2, sysdate);

The changed date as of current time:

SQL> select * from t;

       ID CHANGED
--------- -----------------
        1 19.09.11 15:29:44
        2 19.09.11 15:32:35

Let's take a 5 sec break and then do the following:

 update t set id = 2 where id = 1;

Obviously it will fail with constraint violation, but it doesn't change the changed attribute as well:

SQL> select * from t;

       ID CHANGED
--------- -----------------
        1 19.09.11 15:29:44
        2 19.09.11 15:32:35

My question is: why is this happening? I'm sure I misunderstand some basic concepts but I can't get the idea.

Thanks in advance for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽梦忆笙歌 2024-12-12 02:31:02

PRAGMA AUTONOMOUS TRANSACTION 保存上下文,打开另一个会话并进行某些操作。提交是必须的,否则更改将会丢失。您可以理解,只有在数据库中的某些块中所做的更改在此会话(自治)中才有意义。

所以,在你的触发器中你什么都不做。
如果我们可以在这种模式下说的话,该变量 :new.changed 在另一个会话中“更改”了。它不会因您的更新而更改。

The PRAGMA AUTONOMOUS TRANSACTION saves the context, opens another session and makes something. Commit is a must, because otherwise the changes will be lost. You can understand that only the changes made in some block in the database makes sense in this session (autonomous).

So, in your trigger you do nothing.
That variable, :new.changed is "changed" in another session, if we can say it in this mode. It is not changed for your update.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文