关于 PLSQL Exit Command 返回状态

Posted

技术标签:

【中文标题】关于 PLSQL Exit Command 返回状态【英文标题】:Regarding PLSQL Exit Command return status 【发布时间】:2011-04-04 04:35:24 【问题描述】:

我有从 unix shell 脚本 test.sh 调用的 test.sql 脚本。当我有异常时,问题出在 test.sql 脚本中,我执行回滚并退出。当涉及到 shell 脚本时,它的退出状态($?)为 0,它被认为是成功的。如何从 test.sql 退出并显示错误状态?

test.sh

sql_script=sql/test.sql

$ORACLE_HOME/bin/sqlplus -s << ENDSQL

$DATABASE_LOGIN@$DATABASE_NAMES[$DMIN_DB]

WHENEVER SQLERROR EXIT 1 ROLLBACK
WHENEVER OSERROR EXIT 1 ROLLBACK

SET HEADING OFF
SET FEEDBACK OFF
SET PAGESIZE 0
SET TRIMSPOOL ON
SET SERVEROUTPUT ON

@$sql_script $PROC_DATE

EXIT
ENDSQL

  if [ $? -ne 0 ]; then
    echo "Error in executing the insertBclErrorReport function."
  fi

test.sql

WHILE i IS NOT NULL LOOP
BEGIN

  insert into test1(field1) values(error(i).amount);

  EXCEPTION
    WHEN others THEN rollback;
  exit;

  END;
END LOOP;

commit;

END;

【问题讨论】:

【参考方案1】:

您的 PL/SQL 块将捕获每个异常并通过简单地回滚来处理它。如果您希望调用者知道存在错误,您很可能只想删除异常处理程序。

您还可以在异常处理程序中包含显式的 RAISE 或 RAISE_APPLICATION_ERROR,但这似乎不是特别有用。由于 SQL*Plus 脚本已经通过回滚事务来对错误做出反应,因此在 PL/SQL 循环中捕获并重新抛出异常不会改变任何行为。它所做的只是隐藏与错误相关的实际行号和调用堆栈,从而使调试错误变得更加困难。

一般来说,如果你不能真正处理一个错误,那么捕捉它是没有意义的。出于同样的原因,如果您需要 WHEN OTHERS,那么您几乎可以肯定无法处理错误并且不应该首先捕获它。现在,如果您实际上正在捕获错误,将错误和整个调用堆栈记录到错误表中,并重新抛出比 Oracle 错误更有意义的自定义错误,那么 WHEN OTHERS 可能是合理的。

【讨论】:

非常感谢您提供的信息。我想知道为什么在您的异常处理程序中包含显式 RAISE 或 RAISE_APPLICATION_ERROR 没有用? 我要把exit语句改成raise; @Arav - 我扩展了我的答案。 RAISE 只会掩盖实际引发错误的位置——这似乎不太可能比简单地删除异常处理程序更有益。【参考方案2】:

我遇到了同样的问题,但经过一段时间的调整,这似乎可以在我的系统上运行:

WHENEVER SQLERROR EXIT SQL.SQLCODE;
variable recordId number;
begin
::::::
exception
  WHEN OTHERS then
       :::::::;
      :recordId:=SQLCODE;
end;
/
exit :recordId;

---on SQL*Plus: Release 11.2.0.1.0 Production

【讨论】:

以上是关于关于 PLSQL Exit Command 返回状态的主要内容,如果未能解决你的问题,请参考以下文章

paramiko exec_command 返回 shell 脚本 exit 值

Oracle存储过程执行报错:无效的sql语句。 在plsql中: execute proc_test_exit_when;

linker command failed with exit code 1

linker command failed with exit code 1 (use -v to see invocation)

dos command

PLSQL 授予用户权限,但仍无法修改数据