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

Posted

技术标签:

【中文标题】超出最大递归 SQL 级别数 (50)【英文标题】:maximum number of recursive SQL levels (50) exceeded 【发布时间】:2014-12-18 02:36:06 【问题描述】:

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

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

【问题讨论】:

“我想在不使用序列的情况下创建主键” - 你能解释一下吗? 所以你正在插入一个表并且插入会导致一个触发器被调用,这会导致另一行被插入,并且插入会导致一个触发器被调用,这会导致另一行被插入并且插入会导致一个调用触发器,导致插入另一行,插入导致调用触发器,导致插入另一行,插入导致调用触发器,导致插入另一行,插入导致调用触发器导致插入另一行,插入导致调用触发器,导致 ... 【参考方案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 变量中插入正确的值。

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

【讨论】:

扩展这个以讨论为什么这种方法存在很大问题(性能、多用户系统等)会非常有用【参考方案2】:

你为什么要这么做?

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

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

    它不适用于并发事务

    当你删除当前的“max”时它会重复数字

【讨论】:

【参考方案3】:

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

您不应该显式调用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 ;
/

【讨论】:

您的SELECT 语句缺少FROM 子句。 嗨 Mureinik,你真是个天才。我没想到会那么容易。仅缺少“from”关键字,但这不是问题。你的想法运作良好。非常感谢。 @JustinCave 过于热衷于删除代码...已修复。感谢您的关注!

以上是关于超出最大递归 SQL 级别数 (50)的主要内容,如果未能解决你的问题,请参考以下文章

Python:超出最大递归深度

Tkinter,错误最大递归深度超出

递归sql级别1出现错误

超出表达式递归级别

kivy 中超出了最大递归深度,但仅在打包时超出,而不是在使用 python 开发应用程序时

Python递归函数错误:“超出最大递归深度” [重复]