2013-02-06 101 views
12
#!/bin/sh 

echo "Please enter evaluate database username" 
read eval_user 
echo "Please enter evaluate database password" 
read eval_pass 
echo "Please enter the database name" 
read db_name 

LOGFILE=shell_log.txt 

$ORACLE_HOME/bin/sqlplus -s /nolog <<-EOF>> ${LOGFILE} 
connect $eval_user/[email protected]$db_name 
WHENEVER OSERROR EXIT 9; 
WHENEVER SQLERROR EXIT SQL.SQLCODE; 
DBMS_OUTPUT.put_line('Connected to db'); 
EOF 

if [ $? != 0 ] 
then 
echo "The upgrade script failed. Please refer to the log results.txt for more information" 
echo "Error code $?" 
exit 0; 
fi 

我输入垃圾值试图强制这个脚本失败。但是,令人烦恼的是,它不断提前没有提及任何错误代码。还有什么需要在这里完成?从shell脚本运行sqlplus时管理错误处理

+0

哪个操作系统用户帐户,你下运行?脚本登录到哪个数据库? – APC

+0

我试过你的脚本,并且日志文件捕获错误代码。这里是从日志文件抓取:'错误: ORA-01017:无效的用户名/密码;登录否认 SP2-0734:未知的命令开头“DBMS_OUTPU ......” - 行的其余ignored.' – Incognito

+0

我想知道,你干嘛在日志文件中获取,当你执行脚本? – Incognito

回答

11

Max说的是正确的。试试这个修改后的脚本

#!/bin/sh 

echo "Please enter evaluate database username" 
read eval_user 
echo "Please enter evaluate database password" 
read eval_pass 
echo "Please enter the database name" 
read db_name 

LOGFILE=shell_log.txt 

sqlplus -s /nolog <<-EOF>> ${LOGFILE} 
WHENEVER OSERROR EXIT 9; 
WHENEVER SQLERROR EXIT SQL.SQLCODE; 
connect $eval_user/[email protected]$db_name 
DBMS_OUTPUT.put_line('Connected to db'); 
EOF 

sql_return_code=$? 

if [ $sql_return_code != 0 ] 
then 
echo "The upgrade script failed. Please refer to the log results.txt for more information" 
echo "Error code $sql_return_code" 
exit 0; 
fi 

请注意使用sql_return_code来捕获SQLPLUS返回码。

DBMS_OUTPUT语句应该失败,并出现错误 - “SP2-0734:未知命令开始...”。您可以在日志文件中找到错误消息。

可以使用错误日志记录工具捕获SQLPLUS 11g中的sp2错误。请查看http://tkyte.blogspot.co.uk/2010/04/new-thing-about-sqlplus.html了解更多信息。

+0

我只得到错误代码122,而不是实际的数据库错误消息。你知道一种捕捉输出的方法吗? – roymustang86

+0

错误消息被重定向到“shell_log.txt”。查看当前目录中的该文件。如果要在shell脚本中捕获输出,则需要删除重定向并将SQLPLUS的输出分配给变量。例如: - 'SQL_RESULT = $(sqlplus -s/nolog << EOF WHENEVER SQLERROR EXIT FAILURE WHENEVER OSERROR EXIT FAILURE SET SERVEROUTPUT ON connect $ eval_user/$ eval_pass @ $ db_name exec DBMS_OUTPUT.put_line('Connected to db'); exit EOF )'在UNIX操作系统 –

+2

shell脚本可以返回代码多达255 所以我不知道如何 WHENEVER SQLERROR EXIT SQL.SQLCODE; 可以正确返回255以上的SQL代码吗? 例如ORA-12703这个字符集不支持转换 其实我只是做了一个测试,跑了一个糟糕的SQL失败与 ORA-00936:(!)缺少表达 坏的sqlplus返回168所以实际的返回码936被包裹在和剩下的人得到了回报。 936%256 = 168。 这不是一个正确的答案。 – Tagar

5

你可能有可能在连接到db之后执行你的when语句(因为你之后提到了它们)。请尝试以下代码: -

$ORACLE_HOME/bin/sqlplus -s /nolog <<-EOF>> ${LOGFILE} 
WHENEVER OSERROR EXIT 9; 
WHENEVER SQLERROR EXIT SQL.SQLCODE; 
connect $eval_user/[email protected]$db_name 
DBMS_OUTPUT.put_line('Connected to db'); 
EOF 
1

您输入假值的事实可能只与登录有关。然后: Check database connectivity using Shell script

WHENEVER ...是SQL脚本执行期间的错误。一旦你成功地连接你的脚本(我现在假设你的问题),你应该得到由WHENEVER ERROR管理的错误类型,因为你忘记EXECDBMS_OUTPUT的行。

0

您只能捕获sql错误或操作系统错误。 dbms_output将在sqlplus级本身失败,所以只要错误设置不会影响它。

3

味与

WHENEVER SQLERROR EXIT SQL.SQLCODE; 

,然后使用

sql_return_code=$? 

答案是不正确的(或在大多数情况下不正确)。见下面的细节。


在UNIX OS shell脚本可以返回代码多达255 例如“不支持ORA-12703这种字符集转换”的返回码应该是12703,但它不适合UNIX 8位返回码。
其实我只是做了一个测试,并且运行了一个不合格的SQL,失败时显示“ORA-00936:missing expression” -
sqlplus返回了168(!)。
所以实际的返回码936被包装在256处,只剩下剩余部分返回。 936%256 = 168。


在Windows上,这可能会工作(未测试),但不是在UNIX上(如上所述进行测试)。


唯一可靠的机制可能是后台处理结果写入日志文件,然后像做

tail -n 25 spool.log | egrep "ORA-" | tail -n 1 | cut -d: -f1 | cut -d- -f2 

所以它会用grep阀芯日志文件,然后切实际的最新ORA-代码。