我的脚本文件有以下代码:
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错误不一样。
当SQL*Plus遇到PL/SQL编译错误时,需要添加什么指令才能退出?
发布于 2016-03-10 10:23:15
您得到的警告不是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
的一个附带说明。它将具有实际的错误代码,例如6550或20001。但是大多数shell只允许错误代码达到较小的值,例如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无关。
https://stackoverflow.com/questions/35903059
复制相似问题