我正在尝试运行一个运行oracle sqlplus的shell脚本(ksh)来在后台运行sql脚本。在sql脚本中我使用WHENEVER SQLERROR EXIT SQL.SQLCODE
来捕获错误代码,以便我可以检查它并退出我的程序,否则继续下一个sql语句。
我不确定我的问题是否在我的shell脚本中捕获错误或使用WHENEVER
?
我正在生成/调用ORA-
错误,但返回代码仍显示为Return_code=0,
(传递)并继续运行下一个脚本。它应该失败并退出程序。
有人可以帮我正确配置此脚本吗?我的if-then-else
逻辑也可能存在缺陷。感谢。
这是我的sql(whatever.sql)脚本调用错误:
WHENEVER SQLERROR EXIT SQL.SQLCODE
begin
SELECT COLUMN_DOES_NOT_EXIST FROM DUAL;
END;
/
这是我的剧本:
KEY=$BASEDIR/.keyinfo;
LOG=$BASEDIR/run_tst.log;
# Check before we run
if [ -f "$KEY" ]
then
IFS="
"
set -A arr $(cat $KEY)
echo "Running Test ===>$TIMESTAMP" >> $LOG 2>&1
/bin/sqlplus ${arr[0]}/${arr[1]} @whenever.sql &
pid1=$!
echo "Waiting for PID:$pid1" >> $LOG 2>&1
wait $pid1
ret=$?
echo "Return_code=$?" >> $LOG 2>&1
if [ $ret !=0 ] #if not success
then
exit $ret
echo "Error found...Return_code=$?" >> $LOG 2>&1
echo "Error found...exiting program ===>$TIMESTAMP" >> $LOG 2>&1
exit 1
else
/bin/sqlplus ${arr[0]}/${arr[1]} @tst2.sql
fi
else
echo "key not found. Exiting. ==>$TIMESTAMP" $LOG 2>&1
fi
exit 0
结果(显示0,因为有错误,应该是0以外的其他内容。)
Running Test ===>20130825-09:25
Waiting for PID:6383
Return_code=0
我也尝试了WHENENVER SQLERROR EXIT 1
,但仍得到Return_code=0
测试结果:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SELECT COLUMN_DOES_NOT_EXIST FROM DUAL;
*
ERROR at line 2:
ORA-06550: line 2, column 10:
PL/SQL: ORA-00904: "COLUMN_DOES_NOT_EXIST": invalid identifier
ORA-06550: line 2, column 3:
PL/SQL: SQL Statement ignored
Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
./run.sh[38]: test: Specify a parameter with this command.
答案 0 :(得分:1)
尝试在脚本末尾添加exit
:
WHENEVER SQLERROR EXIT SQL.SQLCODE
begin
SELECT COLUMN_DOES_NOT_EXIST FROM DUAL;
END;
EXIT;
编辑:假设sqlplus返回错误代码,请尝试删除脚本中的后台进程。它可以缩写为:
/bin/sqlplus ${arr[0]}/${arr[1]} @whenever.sql && /bin/sqlplus ${arr[0]}/${arr[1]} @another.sql || echo "Error..."
答案 1 :(得分:1)
当您使用以下内容显示返回代码时:
ret=$?
echo "Return_code=$?" >> $LOG 2>&1
... $0
现在是前一行ret
的分配结果,而不是之前的sqlplus
,所以它始终是零。您还可以在if
区域中提前退出,之后您将看不到这些消息,并且您的测试条件缺少空格(我更喜欢-ne
到!=
) :
...
ret=$?
echo "Return_code=$ret" >> $LOG 2>&1
if [ $ret -ne 0 ] #if not success
then
echo "Error found...Return_code=$ret" >> $LOG 2>&1
echo "Error found...exiting program ===>$TIMESTAMP" >> $LOG 2>&1
exit $ret
else
...
我也更喜欢将变量括在大括号中,例如${ret}
,但我认为这是一个品味问题,除非有歧义。您也可以使用sqlplus
标记来呼叫-s
,以便在日志中隐藏横幅广告。