超出了最大递归SQL级别数(50)

时间:2014-12-18 02:36:06

标签: oracle plsql triggers

我想在不使用序列的情况下创建主键,但我不介意使用触发器。 我正在使用oracle 11gR2。 我的脚本包含以下内容。 一个。创建表(dept2) 湾插入样本数据 C。创建触发器(查找最大值,添加1,插入) d。插入另一条记录(触发器应该触发) 它给出了上述错误。 下面是我的剧本。


drop table dept2 ;
create table dept2
(
deptno number(2),
dname varchar2(20),
mgr number(3)
) ;

insert into dept2 values (11, 'a', 23) ;
insert into dept2 values (12, 'b', 24) ;

select * from dept2 ;

CREATE OR REPLACE TRIGGER trig_deptno2
BEFORE INSERT ON dept2
FOR EACH ROW
DECLARE v_deptno NUMBER(2) ;
BEGIN
    SELECT MAX(deptno) INTO v_deptno
    FROM dept2 ;
    INSERT INTO dept2 VALUES
    ((v_deptno + 1), :NEW.dname, :NEW.mgr) ;
END trig_deptno2 ;
/
SHOW ERR
L

insert into dept2 (dname, mgr) values ('d', 24) ;
select * from dept2 ;
L

有谁能告诉我错误在哪里或我如何纠正错误?

3 个答案:

答案 0 :(得分:4)

你在插入"之前正在做#34;触发。在这样的触发器中,您不会插入到同一个表中 - 否则,您将获得无限循环。只需赋值给变量值:

CREATE OR REPLACE TRIGGER trig_deptno2
BEFORE INSERT ON dept2
FOR EACH ROW
DECLARE v_deptno NUMBER(2) ;
BEGIN
    SELECT coalesce(MAX(deptno) + 1, 1) INTO :new.deptno
    FROM dept2 ;
END trig_deptno2 ;

触发器完成后,它将从new变量中插入正确的值。

我只想说序列存在是有原因的,你应该将它们用于此目的。试图模仿他们的功能可能会导致错误。

答案 1 :(得分:4)

你为什么要这样做?

如果您需要自动生成的序列号,请使用序列。

SELECT MAX(id) + 1的两个主要问题:

  1. 它不适用于并发事务

  2. 删除当前“max”

  3. 时会重复数字

答案 2 :(得分:1)

插入dept2时会触发您的触发器,然后在insert上执行dept2,这会导致触发器在无限递归中重新触发等。

你不应该明确地调用insert - 只需更新:NEW记录,一旦触发完成,更新的记录将被插入表中:

CREATE OR REPLACE TRIGGER trig_deptno2
BEFORE INSERT ON dept2
FOR EACH ROW
DECLARE v_deptno NUMBER(2) ;
BEGIN
    SELECT MAX(deptno) + 1 INTO :NEW.deptno
    FROM   dept2;
END trig_deptno2 ;
/