当PL / SQL编译失败时,如何使SQL * Plus退出

时间:2016-03-09 21:32:42

标签: oracle plsql sqlplus

我的脚本文件包含以下代码:

WHENEVER SQLERROR EXIT SQL.SQLCODE

@pkg_t.pks
@pkg_t.pkb

我从SQL * Plus运行该脚本。如果pkg_t.pkb无效,我会看到:

Warning: Package created with compilation errors.

但SQL * Plus不会退出。我知道pkg_t.pkb有一个PL / SQL错误编译,它与SQL错误不同。

需要添加什么指令才能在遇到PL / SQL编译错误时退出SQL * Plus?

1 个答案:

答案 0 :(得分:4)

您收到的警告不是PL / SQL错误或SQL错误。 PL / SQL运行时错误会导致类似ORA-06550的内容,whenever sqlerror将捕获该内容,并且脚本将使用该代码退出。您虽然看到了编译错误,但这与客户端生成的错误不同。

捕获它的一种方法是检查存储在数据字典中的错误:

WHENEVER SQLERROR EXIT SQL.SQLCODE

@pkg_t.pks
@pkg_t.pkb

declare
  l_errors pls_integer;
begin
  select count(*) into l_errors from user_errors;
  if l_errors > 0 then
    raise_application_error(-20001, 'Stored PL/SQL has compilation errors');
  end if;
end;
/

exit 0;

如果包装规格或正文出现错误,则计数将为非零,您将看到:

declare
*
ERROR at line 1:
ORA-20001: Stored PL/SQL has compilation errors
ORA-06512: at line 6

您还可以在user_objects中查看对象状态。如果你想检查一个特定的对象你可以命名它,但这会使它变得不那么灵活;如果您期望那么可能有必要存在其他现有的无效对象。保持通用意味着你可以有一个单独的脚本,你可以反复调用以尽早发现错误,比如check_errors.sql只包含:

declare
  l_errors pls_integer;
begin
  select count(*) into l_errors from user_errors;
  if l_errors > 0 then
    raise_application_error(-20001, 'Stored PL/SQL has compilation errors');
  end if;
end;
/

然后你可以这样做:

@pkg_t.pks
@check_errors
@pkg_t.pkb
@check_errors

当然,您可以让脚本更加精彩,并进行其他检查。如果您现有的.pks和.pkb脚本已经不这样做,您可以添加show errors,以便查看实际问题。

关于SQL.SQLCODE的附注。那将有实际的错误代码,例如但是,大多数shell只允许错误代码达到较小的值,例如6550或20001. 127或255.这意味着实际的错误代码将被包装,因此它不太可能有意义,但更重要的是,它可能会有一个错误代码,恰好包装到127或255。零 - 这意味着如果您正在检查返回代码,您可能会错误地认为它是成功的。例如,如果我完成了:

raise_application_error(-20224, 'Stored PL/SQL has compilation errors');

然后-20224值将换算为零; SQL * Plus将退出该代码,但如果我在bash中检查$?它将是0,看起来它已经成功了。类似地,-20223将换行为255,而-20225将换行为1 - bash会将两者视为错误,但不会指示实际错误是什么。

因此使用固定值会更安全。我经常只使用whenever sql error exit failure,通常添加rollback,但如果你只做DDL则不相关。