关于PLSQL Exit Command返回状态

时间:2011-04-04 04:35:25

标签: sql oracle bash plsql oracle10g

我有从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;

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:0)

我遇到了同样的问题,但经过一段时间的调整后,这似乎适用于我的系统:

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