2013-02-06 601 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-代碼。