RDB 中数据库触发器和递归的乐趣

发布于 2024-08-14 04:09:57 字数 1020 浏览 1 评论 0原文

这周我遇到了一个问题(幸运的是我已经以更好的方式解决了);

  • 我需要保持数据库中的几个字段不变。

因此,我编写了一个脚本来在表上放置一个触发器,当发生插入或更新时,该脚本会将值设置回预设数字。

数据库是在 VMS 上运行的 RDB(但我有兴趣了解 SQLServer 的相似之处)。

以下是触发器:

drop trigger my_ins_trig;
drop trigger my_upd_trig;

  !
  !++ Create triggers on MY_TABLE
  CREATE TRIGGER my_ins_trig AFTER INSERT ON my_table
         WHEN somefield = 2
  (UPDATE my_table table1
   SET table1.field1 = 0.1,
       table1.field2 = 1.2
   WHERE  my_table.dbkey = table1.dbkey)
  FOR EACH ROW;

  CREATE TRIGGER my_upd_trig AFTER UPDATE ON my_table
         WHEN somefield = 2
  (UPDATE my_table table1
   SET table1.field1  = 0.1,
       table1.field2  = 1.2
   WHERE  my_table.dbkey = table1.dbkey)
  FOR EACH ROW;

提问时间

我希望这会形成无限递归 - 但似乎并非如此? 任何人都可以向我解释 RDB 如何以一种或另一种方式处理这个问题......或者其他数据库如何处理它。

[注意:我知道这是一种糟糕的方法,但各种问题和复杂性意味着即使这在代码中很简单 - 它也不能以最好/最简单的方式完成。值得庆幸的是,我没有以这种方式实现它,但我想询问 SO 社区对此的想法。 ]

提前致谢

I had a problem this week (which thankfully I've solved in a much better way);

  • I needed to keep a couple of fields in a database constant.

So, I knocked up a script to place a Trigger on the table, that would set the value back to a preset number when either an insert, or update took place.

The database is RDB running on VMS (but i'd be interested to know the similarities for SQLServer).

Here are the triggers:

drop trigger my_ins_trig;
drop trigger my_upd_trig;

  !
  !++ Create triggers on MY_TABLE
  CREATE TRIGGER my_ins_trig AFTER INSERT ON my_table
         WHEN somefield = 2
  (UPDATE my_table table1
   SET table1.field1 = 0.1,
       table1.field2 = 1.2
   WHERE  my_table.dbkey = table1.dbkey)
  FOR EACH ROW;

  CREATE TRIGGER my_upd_trig AFTER UPDATE ON my_table
         WHEN somefield = 2
  (UPDATE my_table table1
   SET table1.field1  = 0.1,
       table1.field2  = 1.2
   WHERE  my_table.dbkey = table1.dbkey)
  FOR EACH ROW;

Question Time

I'd would expect this to form an infinite recursion - but it doesnt seem to?
Can anyone explain to me how RDB deals with this one way or another...or how other databases deal with it.

[NOTE: I know this is an awful approach but various problems and complexities meant that even though this is simple in the code - it couldn't be done the best/easiest way. Thankfully I haven't implemented it in this way but I wanted to ask the SO community for its thoughts on this. ]

Thanks in advance

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

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

发布评论

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

评论(1

墨小墨 2024-08-21 04:09:57

编辑:看来Oracle RDB 只是简单地不执行导致递归的嵌套触发器。摘自论文:“只要不发生递归,触发器就可以嵌套其他触发器。”我将把剩下的答案留给其他想了解其他数据库中的递归触发器的人。< /strong>

首先回答你的问题 - 这取决于数据库。完全有可能 在您正在处理的实例上关闭触发递归。正如您可以想象的那样,如果处理不当,触发器递归可能会导致各种混乱,因此 SQL Server 允许您完全禁用它。

其次,我建议也许有一种更好的方法可以在没有触发器的情况下获得此功能。您可以获得 SQL Server 基于视图的行级安全性。使用 Oracle VPD 可以实现相同的结果。

或者,如果您试图保护其配置值,我会将它们全部分组到一个表中并对其应用权限(比基于行的安全性更简单)。

edit: It seems Oracle RDB just plain doesnt execute nested triggers that result in recursion. From the paper: 'A trigger can nest other triggers as long as recursion does not take place.' I'll leave the rest of the answer here for anyone else wondering about recursive triggers in other DBs.

Well firstly to answer your question - it depends on the database. Its entirely possible that trigger recursion is turned off on the instance you are working on. As you can imagine, trigger recursion could cause all kinds of chaos if handled incorrectly so SQL Server allows you to disable it altogether.

Secondly, I would suggest that perhaps there is a better way to get this functionality without triggers. You can get view based row level security with SQL Server. The same outcome can be achieved with Oracle VPDs.

Alternatively, if its configuration values you are trying to protect, I would group them all into a single table and apply permissions on that (simpler than row based security).

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