0

我正在尝试运行运行 oracle sqlplus 的 shell 脚本 (ksh) 以在后台运行 sql 脚本。在我WHENEVER SQLERROR EXIT SQL.SQLCODE用来捕获错误代码的 sql 脚本中,我可以检查它并退出我的程序,否则继续下一个 sql 语句。

我不确定我的问题是在我的 shell 脚本中捕获错误还是使用WHENEVER? 我正在产生/调用ORA-错误,但返回代码仍显示为Return_code=0,(通过)并继续运行下一个脚本。它应该失败并退出程序。

有人可以帮我正确配置这个脚本吗?我的if-then-else逻辑可能也有缺陷。谢谢。

这是我调用错误的 sql (whenever.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.
4

2 回答 2

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..."
于 2013-08-25T16:32:13.397 回答
1

当您显示返回码时:

ret=$?
echo "Return_code=$?"  >> $LOG 2>&1

...$0现在是ret上一行分配的结果,而不是较早的sqlplus,所以它总是 gping 为零。您还可以在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隐藏日志中的横幅。

于 2013-08-25T22:26:03.877 回答