我的脚本文件包含以下代码:
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?
答案 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则不相关。