首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当PL/SQL编译失败时如何使SQL*Plus退出

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

Stack Overflow用户
提问于 2016-03-09 21:32:42
回答 1查看 1.8K关注 0票数 2

我的脚本文件有以下代码:

代码语言:javascript
运行
复制
WHENEVER SQLERROR EXIT SQL.SQLCODE

@pkg_t.pks
@pkg_t.pkb

我正在从SQL*Plus运行这个脚本。如果pkg_t.pkb无效,我看到:

代码语言:javascript
运行
复制
Warning: Package created with compilation errors.

但是SQL*Plus不退出。据我所知,pkg_t.pkb有一个PL/SQL错误编译,这与一个SQL错误不一样。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-10 10:23:15

您得到的警告不是PL/SQL错误,也不是SQL错误。PL/SQL运行时错误将导致类似于ORA-06550的情况,您的whenever sqlerror将捕捉到该错误,并且脚本将随该代码退出。不过,您看到的是一个编译错误,这是不同的,这是由客户机生成的。

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

代码语言:javascript
运行
复制
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;

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

代码语言:javascript
运行
复制
declare
*
ERROR at line 1:
ORA-20001: Stored PL/SQL has compilation errors
ORA-06512: at line 6

您还可以在user_objects中检查对象状态。如果您想要检查某个特定的对象,您可以给它命名,但这会使它变得不那么灵活;如果您希望周围有其他现有的无效对象,则可能是必要的。保持它的泛型意味着您可以拥有一个单独的脚本,您可以反复调用该脚本来尽早捕获错误,比如check_errors.sql,它只包含:

代码语言:javascript
运行
复制
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;
/

然后你就可以:

代码语言:javascript
运行
复制
@pkg_t.pks
@check_errors
@pkg_t.pkb
@check_errors

当然,您可以使脚本变得更时尚,并进行其他检查。如果您现有的.pks和.pkb脚本还没有这样做,您可以添加show errors,这样就可以看到实际的问题。

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

代码语言:javascript
运行
复制
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无关。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35903059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档