Sql Oracle DDL执行(带即时模式和错误)

Sql Oracle DDL执行(带即时模式和错误),sql,oracle,show,mode,Sql,Oracle,Show,Mode,在对execute immediate和error handling的各种问题进行了大约两个小时的研究之后,我认为我没有遇到我将要提出的问题。我已将我的问题简化为以下示例。问题是: 当我使用变量中的create text和create text中的语法错误在立即模式下执行create过程时,execute immediate调用抛出一个错误,指示它失败。但我无法理解潜在的错误或其文本 但是,当我直接在sqlplus(w/o中间模式)中创建同一个进程时,得到错误是完全可行的 那么,如何理解导致即时

在对execute immediate和error handling的各种问题进行了大约两个小时的研究之后,我认为我没有遇到我将要提出的问题。我已将我的问题简化为以下示例。问题是:

当我使用变量中的create text和create text中的语法错误在立即模式下执行create过程时,execute immediate调用抛出一个错误,指示它失败。但我无法理解潜在的错误或其文本

但是,当我直接在sqlplus(w/o中间模式)中创建同一个进程时,得到错误是完全可行的

那么,如何理解导致即时模式失败的错误呢

我在输出中加入了我的评论(MOP),并减少了空行数:

SQL*Plus: Release 10.2.0.1.0 - Production on Mon Mar 25 15:57:06 2013
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> set serveroutput on

SQL> declare
  2    eSQL varchar(568);
  3  begin
  4        eSQL := 'create or replace procedure MOPMOP
  5  as
  6  begin
  7      select 1 from dual;
  8  end;
  9  ';
 10        execute immediate eSQL;
 11  end;
 12  /
ERROR:
ORA-24344: success with compilation error
ORA-06512: at line 10
Warning: PL/SQL compilation errors.
这很好。有一个编译错误。那么,现在让我问一下编译错误是什么:

SQL> show errors;
No errors.
SQL> show errors;
Errors for PROCEDURE MOPMOP:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/5  PLS-00428: an INTO clause is expected in this SELECT statement
SQL> 
这不好。有一个编译错误。那是什么!?!?!?与之相比:

SQL> create or replace procedure MOPMOP
  2  as
  3  begin
  4      select 1 from dual;
  5  end;
  6  /

Warning: Procedure created with compilation errors.
这很好。有一个编译错误。那么,现在让我问一下编译错误是什么:

SQL> show errors;
No errors.
SQL> show errors;
Errors for PROCEDURE MOPMOP:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/5  PLS-00428: an INTO clause is expected in this SELECT statement
SQL> 
这很好。有一个编译错误。现在我知道是什么了


那么,如何获得中间模式以吐出基本(00428)错误?

您不能使用从双模式选择1。。。在PL/SQL中。必须使用select into。在这两种情况下,您都在创建PL/SQL过程,而不是一些SQL脚本

declare
   x number;
begin 
  select 1 into x from dual;
end;
/

declare
  procedure MOPMOP
  as
    x number;
 begin
   select 1 into x from dual;
   dbms_output.put_line(x);
 end MOPMOP;
begin
 MOPMOP;
end;
/
避免使用ORA-24344-尽管我可能永远不会为此使用动态sql:

declare
  eSQL varchar(568);
  x number;
begin  
  eSQL := 'create or replace procedure MOPMOP as 
           begin 
             select 1 into x from dual; 
           end;';            
  execute immediate eSQL;
  EXCEPTION WHEN OTHERS THEN NULL;
end;
/

当您单独运行
show errors
时,它将显示sqlplus本身之前所做的任何“create”/“alter”的错误,在这种情况下,它什么都不是(因为动态SQL对sqlplus隐藏了它)

您必须明确表示,您希望看到本案例中程序的错误:

SQL> declare
  2    eSQL varchar(568);
  3  begin
  4        eSQL := 'create or replace procedure MOPMOP
  5  as
  6  begin
  7      select 1 from dual;
  8  end;
  9  ';
 10        execute immediate eSQL;
 11  end;
 12  /
ERROR:
ORA-24344: success with compilation error
ORA-06512: at line 10



Warning: PL/SQL compilation errors.

SQL> show errors procedure mopmop
Errors for PROCEDURE MOPMOP:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/5      PLS-00428: an INTO clause is expected in this SELECT statement
SQL>
由于create在服务器端运行,而不是通过sqlplus运行,sqlplus不知道故障,因此无法正确获取错误

此外,如果您之前有过失败,它将保留以下内容:

SQL> create or replace procedure MOPMOP2
  2  as
  3  begin
  4      select 1 from dual;
  5  end;
  6  /

Warning: Procedure created with compilation errors.

SQL> declare
  2    eSQL varchar(568);
  3  begin
  4        eSQL := 'create or replace procedure MOPMOP
  5  as
  6  begin
  7      select 1 from dual;
  8  end;
  9  ';
 10        execute immediate eSQL;
 11  end;
 12  /
ERROR:
ORA-24344: success with compilation error
ORA-06512: at line 10



Warning: PL/SQL compilation errors.

SQL> show errors
Errors for PROCEDURE MOPMOP2:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/5      PLS-00428: an INTO clause is expected in this SELECT statement
SQL>

我认为他的代码只是说明了需要,并允许我们重现这个问题。是的,这只是一个复制。@mpersico仅供参考:即使您使用了与我的示例中相同的语法,您也会看到相同的错误消息。注释“我的代码”中的异常部分,您将看到相同的错误消息。在我的代码中,我向您展示了如何修复代码以及如何删除消息。只是想帮忙,不在乎分数。。。