Oracle触发器 – 变异表的问题

我的桌子:
TableA (id number,state number)
TableB (id number,tableAId number,state number)
TableC (id number,tableBId number,state number)

因此TableC中的项是TableB的子项,TableB中的项是TableA的子项.反之亦然 – TableA中的项是TableB的父项,TableB中的项是TableC的父项.

我想控制父项的状态……比方说,我们有这些数据:

TableA (id,state): 
1,40

TableB (id,tableAId,1,40
2,60

TableC (id,tableBId,50
3,2,60
4,70

父母国家应该始终保持他孩子最小的状态.所以如果我们现在像这样更新TableC:

update TableC set state = 50 where Id = 1;

我的触发器应该自动更新TableB(设置状态= 50,其中id = 1),然后更新TableA(设置状态= 50,其中id = 1)

我想用触发器(在表A,表B,表C上进行更新,插入,删除之后)执行此操作,以便在执行每个操作后执行以下步骤:

>获取父ID
>从当前父母的所有孩子中找到最小的状态
>如果所有子项的最小状态大于父项的状态,则更新父项

如何避免“改变表错误”?在此示例中是否可以节省使用自治事务?我看到一些意见,变异表错误表明应用程序的逻辑存在缺陷 – 这是真的吗?如何更改我的逻辑以防止此错误

谢谢

编辑:
感谢所有伟大的答案!

最后,我使用了触发器(感谢Vincent Malgrat,他指出了Tom Kyte的文章).

编辑:
在REAL END中,我使用了存储过程并删除了触发器:)

您已经注意到,使用触发器很难回答您的业务需求.原因是Oracle可以为单个查询(并行DML)同时更新/插入具有多个线程的表.这意味着您的会话无法在更新发生时查询它更新的表.

如果你真的想用触发器做这个,你必须遵循kind of logic shown in this article by Tom Kyte.你可以看到它并不简单.

还有另一种更简单,更优雅,更易于维护的方法:使用程序.撤消对应用程序用户的更新/插入权限,并编写一组允许应用程序更新状态列的过程.

这些过程将锁定父行(以防止多个会话修改同一组行),并以高效,可读和易于维护的方式应用您的业务逻辑.

相关文章

数据库版本:11.2.0.4 RAC(1)问题现象从EM里面可以看到,在23号早上8:45~8:55时,数据库等待会话暴增...
(一)问题背景最近在对一个大约200万行数据的表查看执行计划时,发现存在异常,理论上应该返回100多万...
(一)删除备份--DELETE命令用于删除RMAN备份记录及相应的物理文件。当使用RMAN执行备份操作时,会在RM...
(1)DRA介绍 数据恢复顾问(Data Recovery Advise)是一个诊断和修复数据库的工具,DRA能够修复数据文...
RMAN(Recovery Manager)是Oracle恢复管理器的简称,是集数据库备份(backup)、修复(restore)和恢复...
(1)备份对象 可以使用RMAN进行的备份对象如下: --整个数据库:备份所有的数据文件和控制文件; --数...