使用行触发器强制连续数字

时间:2018-04-07 10:07:42

标签: oracle plsql

我有一张桌子位置'列名为' 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;
/

这是我第一次尝试插入新行时的工作原理,但是一旦成功插入了一行,无论我接下来要插入什么行,都会触发此触发器。

2 个答案:

答案 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)

其他人已经提到过使用序列和/或身份条款,但这里有一些更基本的触发器方法。

它无法正常工作。

触发器不起作用的原因有两个

  1. 您无法在引用触发表的触发器中运行查询。你会收到一个错误,说#34;表正在变异",所以从一开始你就会遇到问题
  2. 这个概念在任何类型的真实数据库中完全崩溃 情况,即系统中有多个用户的情况。 让我们说表中目前有10条记录,2条 用户想要添加记录。两者都会发出一个计数(*) 会得到' 10'因此两者都会尝试添加一行 标识符11。
  3. 我已经用这里的触发器完成了关于这个常见漏洞的整个视频

    https://www.youtube.com/watch?v=hdU92bsByOQ

    但只是......不要使用触发器。如果这是一门课程课程,那么也应该向教师指出 - 教授这种方法是一种可怕的做法(针对这个问题)。