Oracle11g:带“的复合触发器”;“关于删除级联”;约束

Oracle11g:带“的复合触发器”;“关于删除级联”;约束,oracle,plsql,oracle11g,triggers,Oracle,Plsql,Oracle11g,Triggers,在Oracle(11.2.0.1)中,我有两个表,比如A和B,它们之间有一个引用约束(“在删除级联中”)A是B的“父级” create table A (id number(9) not null primary key); create table B (id number(9) not null primary key, parent_id not null references A(id) on delete cascade); 子表在从中删除时也有一个相关的复合触发器(主要目的是在一系

在Oracle(11.2.0.1)中,我有两个表,比如AB,它们之间有一个引用约束(“在删除级联中”)AB的“父级”

create table A (id number(9) not null primary key);
create table B (id number(9) not null primary key, parent_id not null references A(id) on delete cascade);
子表在从中删除时也有一个相关的复合触发器(主要目的是在一系列复杂的完整性检查中避免突变错误)

使用这些表的算法之一如下所示:

  • 将从B中删除具有特定父级id的所有行
  • 如果没有留下子行,则进行附加检查
  • 从父级A中删除此特定id 在我们的生产环境中,步骤3首先在string
    b_collection.first.处生成异常
    ORA-06502:PL/SQL:numeric或value error
    。。b_集合。最后一次
    。这意味着从父表中删除会导致在子表上触发触发器,即使影响上没有可能的子行。这可能有点道理,因为当触发触发器时集合不存在,并且第一个和最后一个集合索引为NULL,但我无法重现这种行为

    在我们的开发环境中,当我试图从B中删除一些不存在的id/parent\u id时,我只得到一个
    ORA-06502
    。当我试图从A中删除一些存在的(没有子行)或不存在的id时,我没有收到任何错误-删除了0行,影响了0个子行。从日志中我可以看出,在这种情况下,与儿童相关的触发器甚至没有被触发。为什么不呢


    你知道为什么所描述的行为会如此不同吗?我错过什么了吗

    当集合为空时,您将得到
    ORA-06502:PL/SQL:numeric或value错误
    异常:

    SQL> declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in numtab.first..numtab.last loop
      6      null;
      7    end loop;
      8  end;
      9  /
    declare
    *
    ERROR at line 1:
    ORA-06502: PL/SQL: numeric or value error
    ORA-06512: at line 5
    
    除非有任何方法可以使集合变得稀疏(即从中间删除一些成员),否则我将使用此循环:

      1  declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in 1..numtab.count loop
      6      null;
      7    end loop;
      8* end;
    SQL> /
    
    PL/SQL procedure successfully completed.
    
    否则,您需要在处理集合之前测试集合是否为空(在已知集合密集的情况下,这对我来说总是过于麻烦):


    每当集合为空时,您将获得
    ORA-06502:PL/SQL:numeric或value错误
    异常:

    SQL> declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in numtab.first..numtab.last loop
      6      null;
      7    end loop;
      8  end;
      9  /
    declare
    *
    ERROR at line 1:
    ORA-06502: PL/SQL: numeric or value error
    ORA-06512: at line 5
    
    除非有任何方法可以使集合变得稀疏(即从中间删除一些成员),否则我将使用此循环:

      1  declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in 1..numtab.count loop
      6      null;
      7    end loop;
      8* end;
    SQL> /
    
    PL/SQL procedure successfully completed.
    
    否则,您需要在处理集合之前测试集合是否为空(在已知集合密集的情况下,这对我来说总是过于麻烦):


    每当集合为空时,您将获得
    ORA-06502:PL/SQL:numeric或value错误
    异常:

    SQL> declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in numtab.first..numtab.last loop
      6      null;
      7    end loop;
      8  end;
      9  /
    declare
    *
    ERROR at line 1:
    ORA-06502: PL/SQL: numeric or value error
    ORA-06512: at line 5
    
    除非有任何方法可以使集合变得稀疏(即从中间删除一些成员),否则我将使用此循环:

      1  declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in 1..numtab.count loop
      6      null;
      7    end loop;
      8* end;
    SQL> /
    
    PL/SQL procedure successfully completed.
    
    否则,您需要在处理集合之前测试集合是否为空(在已知集合密集的情况下,这对我来说总是过于麻烦):


    每当集合为空时,您将获得
    ORA-06502:PL/SQL:numeric或value错误
    异常:

    SQL> declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in numtab.first..numtab.last loop
      6      null;
      7    end loop;
      8  end;
      9  /
    declare
    *
    ERROR at line 1:
    ORA-06502: PL/SQL: numeric or value error
    ORA-06512: at line 5
    
    除非有任何方法可以使集合变得稀疏(即从中间删除一些成员),否则我将使用此循环:

      1  declare
      2    type t is table of number;
      3    numtab t := t();
      4  begin
      5    for i in 1..numtab.count loop
      6      null;
      7    end loop;
      8* end;
    SQL> /
    
    PL/SQL procedure successfully completed.
    
    否则,您需要在处理集合之前测试集合是否为空(在已知集合密集的情况下,这对我来说总是过于麻烦):


    我想出来了。11.2.0.1版本的复合触发器(Doc ID 8830338.8)中未执行的
    Bug 8830338-BEFORE和AFTER语句
    。自从补丁集11.2.0.2发布以来,它就被修复了,因为这样一个带有after语句的复合触发器应该被触发,并且以一种不好的方式结束。

    我找到了答案。11.2.0.1版本的复合触发器(Doc ID 8830338.8)中未执行的
    Bug 8830338-BEFORE和AFTER语句
    。自从补丁集11.2.0.2发布以来,它就被修复了,因为这样一个带有after语句的复合触发器应该被触发,并且以一种不好的方式结束。

    我找到了答案。11.2.0.1版本的复合触发器(Doc ID 8830338.8)中未执行的
    Bug 8830338-BEFORE和AFTER语句
    。自从补丁集11.2.0.2发布以来,它就被修复了,因为这样一个带有after语句的复合触发器应该被触发,并且以一种不好的方式结束。

    我找到了答案。11.2.0.1版本的复合触发器(Doc ID 8830338.8)中未执行的
    Bug 8830338-BEFORE和AFTER语句
    。自从补丁集11.2.0.2发布以来,它就被修复了,因为这样一个带有after语句的复合触发器本应该被触发,并且以一种糟糕的方式结束。

    感谢您的快速回复!我知道如何正确处理空集合,但真正困扰我的是触发器的魔力。谢谢你的快速回复!我知道如何正确处理空集合,但真正困扰我的是触发器的魔力。谢谢你的快速回复!我知道如何正确处理空集合,但真正困扰我的是触发器的魔力。谢谢你的快速回复!我知道如何正确处理空集合,但真正困扰我的是触发器的魔力。