我的代码不起作用,Oracle告诉我触发器是在生成错误的情况下创建的。显然我无法得到更精确的关于构建错误的信息.
我以前真的没有做过很多SQL,所以我对语法不太熟悉。我有预感这是我的如果存在(选择.)然后说甲骨文不喜欢,我一直在谷歌寻找类似的例子,但我没有找到任何在我的情况下有效的东西。
关于密码:
你知道怎么回事吗?
发布于 2014-03-28 15:51:23
首先,如果您使用的是SQL*Plus,当您创建一个对象并被告知存在编译错误时,show errors命令将显示这些错误。
如果运行show errors,就会被告知IF EXISTS不是有效的语法。你可以做这样的事
SELECT COUNT(*)
INTO l_cnt
FROM <<rest of query>>
IF( l_cnt > 0 )
THEN
RAISE_APPLICATION_ERROR ...
END IF;但是,一旦修复了编译错误,就会出现运行时错误。在surveillance上的行级触发器中,通常不能查询surveillance (如果您所做的只是保证只插入一行的INSERT VALUES )。如果这样做,您将在运行时得到一个可变的触发错误。
从数据模型的角度来看,当您发现自己设计了一个表,其中特定行的有效数据依赖于存储在同一表的其他行中的数据时,您通常违反了规范化原则,并且通常可以更好地修复底层数据模型。
如果您真的决定保留数据模型,我更愿意创建一个物化视图,该视图只为违反您的条件的行创建刷新提交的数据。然后,可以对该物化视图施加约束,在违反标准时在提交时抛出错误。这将需要表上的物化视图日志。
如果您确实希望保留数据模型,并且希望使用触发器来执行逻辑,则需要经典的三种触发器解决方案(如果使用11.2或更高版本,则需要由三部分组成的复合触发器)。您可以创建一个包含主键值集合的包。前置语句触发器将初始化集合。行级触发器将插入插入和/或更新到此集合中的行的主键。然后,after语句触发器将迭代这个集合,并实现任何您想要的检查。这是很多移动的碎片,这也是为什么我通常反对它。
此外,即使你让所有这些部分工作,你的逻辑不会保护你在一个多用户的环境。当多个用户同时访问系统时,完全有可能一个用户将插入一行,第二个用户将插入另一个具有重叠范围的行,然后每个会话都将提交。在这种情况下,这两组触发器都将允许更改,但仍然会在表中留下违反您的需求的数据。物化视图将在多用户环境中正常工作,因为它是在提交时而不是在插入时强制执行的。如果希望触发器在多用户环境中工作,则必须添加其他逻辑,以强制序列化,从而阻止第二个会话的insert在第一个会话提交或回滚之前运行。这增加了复杂性,降低了可伸缩性,并取决于实现方式,可能会造成支持噩梦。
https://stackoverflow.com/questions/22717136
复制相似问题