超过递归SQL级别的最大数量(50)(maximum number of recursive SQL

2019-10-21 10:52发布

我想不使用序列创建主键,但我不介意使用触发器。 我使用的是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

谁能告诉我哪里是错误的或我怎么能改正错误?

Answer 1:

你正在做一个“插入之前”触发。 在这样的触发,你不插入到同一个表 - 否则,你可以得到一个无限循环。 只是赋予变量值:

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变量。

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



Answer 2:

你为什么要这么做?

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

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

  1. 它不与并发事务工作

  2. 当你删除当前的“最大”它重复号码



Answer 3:

将你的触发器触发时dept2 ,然后执行insertdept2 ,这将导致触发重新火灾等以无限递归。

你不应该叫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 ;
/


文章来源: maximum number of recursive SQL levels (50) exceeded