oracle 触发器 判断insert,sql – 在BEFORE INSERT触发器(Oracle)中使用IF EXISTS(SELECT …)...

首先,如果您正在使用SQL * Plus,当您创建一个对象并被告知存在编译错误时,命令show errors将显示错误.

如果你运行show errors,你会被告知IF EXISTS是无效的语法.你可以做点什么

SELECT COUNT(*)

INTO l_cnt

FROM <>

IF( l_cnt > 0 )

THEN

RAISE_APPLICATION_ERROR ...

END IF;

但是,一旦修复了编译错误,就会出现运行时错误.在监视的行级触发器中,您通常不能查询监视(如果您正在执行的是INSERT VALUES,则可以保证仅插入单行).如果这样做,您将在运行时遇到变异触发错误.

从数据模型的角度来看,当您发现自己设计一个表,其中特定行的有效数据取决于存储在同一个表的其他行中的数据时,您通常违反了规范化原则,并且通常更好地修复了基础数据模型.

如果你真的决定保留数据模型,我宁愿创建一个在提交时刷新的物化视图,它只包含违反你标准的行的数据.然后,您可以在物化视图上设置约束,在违反条件时在提交时抛出错误.这将需要您桌面上的物化视图日志.

如果您真的想要保留数据模型并且想要使用触发器强制执行逻辑,那么您需要经典的三触发解决方案(如果您使用11.2或更高版本,则需要具有三个部分的复合触发器).您将创建一个包含主键值集合的包. before语句触发器将初始化集合.行级触发器将插入已插入和/或更新到此集合中的行的主键.然后一个after语句触发器将遍历此集合并实现您想要的任何检查.然而,这是很多动人的作品,这就是为什么我通常会反对它.

此外,即使您将所有这些部分都工作,您的逻辑也无法在多用户环境中保护您.当您有多个用户同时访问系统时,一个用户完全可能插入一行,第二个用户将插入另一个具有重叠范围的行,然后每个会话都将提交.在这种情况下,两组触发器都允许更改,但您仍然会在表格中留下违反要求的数据.物化视图,因为它在提交时而不是在插入时强制执行,将在多用户环境中正常工作.如果您希望触发器在多用户环境中工作,则必须通过添加其他逻辑来进一步使它们复杂化,这些逻辑强制执行序列化,阻止第二个会话的插入运行,直到第一个会话提交或回滚.这增加了复杂性,降低了可扩展性,并且取决于它的实现方式,可能会导致支持噩梦.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值