Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle在以后的块中使用第一个块的异常处理程序_Oracle_Plsql_Flyway - Fatal编程技术网

Oracle在以后的块中使用第一个块的异常处理程序

Oracle在以后的块中使用第一个块的异常处理程序,oracle,plsql,flyway,Oracle,Plsql,Flyway,我遇到了这样一种行为:我试图在Flyway脚本中为几个Oracle PL/SQL块使用特定于大小写的异常处理程序,Oracle显然与它记录的异常处理程序范围相矛盾,将所有异常发送到第一个块的异常处理程序。例如,在此代码中: begin begin execute immediate ' create table "test" ( "id" number not null, "name" varchar2(100) not null, constraint "test_p

我遇到了这样一种行为:我试图在Flyway脚本中为几个Oracle PL/SQL块使用特定于大小写的异常处理程序,Oracle显然与它记录的异常处理程序范围相矛盾,将所有异常发送到第一个块的异常处理程序。例如,在此代码中:

begin

  begin
    execute immediate '
create table "test" (
  "id" number not null,
  "name" varchar2(100) not null,
  constraint "test_pk" primary key ("id")
)
';
  exception
  when others then
    if sqlcode != -955 then raise; end if;
  end;

  begin
    execute immediate 'fail to create index "test_name_idx" on "test" ("name")';
  exception
  when others then
    if sqlcode != -6512 then raise; end if;
  end;

end;
ORA-06512异常未被捕获,引发的异常标记为第13行

将这些块包装成更多的块没有帮助


这是怎么回事?如何阻止这种情况发生?

这似乎是一个bug,它(到目前为止)已在11.2.0.4、12.1.0.2和12.2.0.1中重现。它似乎不需要DDL,也不需要在第一个子块中执行任何实际操作(尽管仅将
null;
作为占位符不会触发它,可能是因为编译器将其删除),但它似乎需要两个异常处理程序中的
if

begin
  begin
    dbms_output.put_line('Dummy message');
  exception
    when others then
      dbms_output.put_line('In first exception handler');
      if 1=1 then
        raise;
      end if;
  end;

  begin
    execute immediate 'invalid';
  exception
    when others then
      dbms_output.put_line('In second exception handler');
      if 1=1 then
        raise;
      end if;
  end;
end;
/

Dummy message
In second exception handler

ORA-00900: invalid SQL statement
ORA-06512: at line 8
ORA-06512: at line 13
与您的示例一样,异常是由第13行引发的,因此应在第18行报告为(重新)引发的;但事实上,它是从第8行提出来的,这是没有意义的。(第13行的
信息仅在12.2中显示;在11.2和12.1中,它只报告了第一个ORA-06512,这相当令人困惑。至少在12.2中,您知道问题的真正所在。)

从调试中可以看出,它实际上没有使用第一个异常处理程序,而是进入了第二个异常处理程序。它“仅”似乎是针对错误的行号进行报告,而不是执行错误的代码

似乎在
提升之前,在
if
中进行实际工作可以解决异常处理部分的问题;这会在第一条中添加一条无法访问的消息:

begin
  begin
    dbms_output.put_line('Dummy message');
  exception
    when others then
      dbms_output.put_line('In first exception handler');
      if 1=1 then
        dbms_output.put_line('This avoids the bug somehow');
        raise;
      end if;
  end;

  begin
    execute immediate 'invalid';
  exception
    when others then
      dbms_output.put_line('In second exception handler');
      if 1=1 then
        raise;
      end if;
  end;
end;
/

Dummy message
In second exception handler

ORA-00900: invalid SQL statement
ORA-06512: at line 19
ORA-06512: at line 14
第二种情况是:

begin
  begin
    dbms_output.put_line('Dummy message');
  exception
    when others then
      dbms_output.put_line('In first exception handler');
      if 1=1 then
        raise;
      end if;
  end;

  begin
    execute immediate 'invalid';
  exception
    when others then
      dbms_output.put_line('In second exception handler');
      if 1=1 then
        dbms_output.put_line('This avoids the bug somehow');
        raise;
      end if;
  end;
end;
/

Dummy message
In second exception handler

ORA-00900: invalid SQL statement
ORA-06512: at line 19
ORA-06512: at line 13
在这两种情况下,报告的行号现在都是正确的。不知怎么的

它不必是一个
dbms\u输出
调用,任何东西似乎都可以工作,例如一个伪过程调用或查询,甚至是一个额外的子块(例如
开始执行立即的'select*from dual';结束;
,即使查询没有执行,因为没有
进入
…)。再次使用
null不起作用

这有点难看,但至少给了你一种阻止它发生的方法


这显然是一种奇怪的、意外的、不一致的行为,而且已经存在了一段时间,因此可能应该通过我的Oracle支持部门将其作为服务请求提出。我看不到任何现有的报告,但我没有仔细查看,因此可能有一份潜伏在某处。

这非常。。。。有趣。如果在第一次提升之前(在If内部)添加一个简单的
dbms\u输出
调用,它会通过livesql.oracle.com上的快速测试报告正确的行号。但是,通过更多的调试,它实际上不会命中第一个异常处理程序(当然,正如您所期望的那样),即使它报告了错误的行号。看起来像一个(解析?)bug,可能在
dbms\u sql
中?也许有兴趣看看它是否表现出相同的不同版本。看起来有点像10g的bug 8856896,但这是12cR2,至少在那个站点是这样。可能是时候向Oracle支持部门提出服务请求了?FWIW,在Oracle 12.1.0.2.0上重现了此问题。顺便说一句,我想知道你为什么要捕捉ORA-06512(“错误在n行”),因为我认为你会感兴趣的实际例外是ORA-00955(“名称已被现有对象使用”)和ORA-01408(“此类列列表已被索引”)。@JeffreyKemp:是的,这只是一个复制案例。