unix脚本 - 无法正确捕获或解释sqlplus中的错误代码

时间:2013-08-25 16:09:50

标签: oracle unix error-handling sqlplus

我正在尝试运行一个运行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.

2 个答案:

答案 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,以便在日志中隐藏横幅广告。