我有一张桌子位置'列名为' p#'。位置列中的所有值必须是连续的,即要插入p#= 2的条目,必须有p#= 1条目。使用的方法必须使用行触发器,如果插入的数据不连续,则会引发应用程序错误。
CREATE OR REPLACE TRIGGER ContinuousPosition
AFTER UPDATE OR INSERT ON Position
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
prevPos NUMBER(8);
BEGIN
SELECT COUNT(*) INTO prevPos FROM Position WHERE p# = (:NEW.p# - 1);
IF prevPos = 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'testError');
END IF;
END;
/
这是我第一次尝试插入新行时的工作原理,但是一旦成功插入了一行,无论我接下来要插入什么行,都会触发此触发器。
答案 0 :(得分:1)
正如评论中已经说过的,您应该更喜欢使用SEQUENCE
中的Oracle Trigger
或使用IDENTITY
列(Oracle 12c +)来增加列。
参考https://oracle-base.com/articles/misc/autonumber-and-identity
和https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1
此外,您自己的TRIGGER
将无法在第一时间运行,您已将其禁用。你应该添加一个这样的条件,以允许插入第一次正常工作。
SELECT COUNT(*)
INTO tot_count
FROM POSITION;
IF tot_count != 0 THEN
...--Other statements
第二个问题是,您应该在每个 commit
之后INSERT
来反映AUTONOMOUS_TRANSACTION
中表格的值。
第三个问题是当有人删除记录时你将如何确保连续?
解决这些问题,并仅在需要时实时使用触发器。
答案 1 :(得分:1)
其他人已经提到过使用序列和/或身份条款,但这里有一些更基本的触发器方法。
它无法正常工作。
触发器不起作用的原因有两个
我已经用这里的触发器完成了关于这个常见漏洞的整个视频
https://www.youtube.com/watch?v=hdU92bsByOQ
但只是......不要使用触发器。如果这是一门课程课程,那么也应该向教师指出 - 教授这种方法是一种可怕的做法(针对这个问题)。