我有从unix shell脚本test.sh调用的test.sql脚本。问题是在test.sql脚本中,当我有一个例外我做回滚并退出。对于shell脚本,它的退出状态($?)为0,它被认为是成功的。我如何从test.sql中以错误状态退出?
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
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;
答案 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