Управление обработкой ошибок при запуске sqlplus из сценариев оболочки

#!/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/$eval_pass@$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

Я ввожу значения мусора, пытаясь заставить этот скрипт с ошибкой. Но, к сожалению, он продолжает двигаться вперед без какого-либо упоминания кода ошибки. Что еще нужно сделать?

5 ответов


то, что говорит Макс, правильно. Попробуйте этот измененный скрипт

#!/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/$eval_pass@$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 должны завершиться с ошибкой - "с пакетом обновления 2-0734: неизвестная команда начала...". Сообщение об ошибке можно найти в файле журнала.

можно поймать ошибки sp2 в SQLPLUS 11g с помощью средства регистрации ошибок. Пожалуйста, взгляните на http://tkyte.blogspot.co.uk/2010/04/new-thing-about-sqlplus.html для получения дополнительной информации.


возможно, что ваши операторы whenever выполняются после установления соединения с БД (поскольку вы упомянули их впоследствии). Попробуйте следующий код :-

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

ответ Аджи с

WHENEVER SQLERROR EXIT SQL.SQLCODE;

и затем с помощью

sql_return_code=$?

- это не правильно (или не правильно в большинстве случаев). Подробнее см. ниже.


сценарий оболочки в ОС UNIX может возвращать коды до 255. Например. "ORA-12703 это преобразование набора символов не поддерживается" код возврата должен быть 12703, но он не вписывается в UNIX 8-битный код возврата.
На самом деле я просто сделал тест и запустил плохой SQL, который терпит неудачу с " Ora-00936: отсутствует выражение" -
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-код.


тот факт, что вы вводите поддельные значения, вероятно, связаны только с логином. Затем: проверьте подключение к базе данных с помощью Shell script

на WHENEVER ... предназначены для ошибок во время выполнения сценария SQL. Как только вы успешно подключитесь к своему скрипту (я предполагаю, что это ваша проблема прямо сейчас), вы должны получить ошибку, управляемую WHENEVER ERROR потому что вы забыли EXEC на вашей линии с DBMS_OUTPUT.


вы можете только поймать ошибку sql или ошибку ОС. Dbms_output завершится ошибкой на уровне sqlplus, поэтому параметр всякий раз, когда ошибка не влияет на него.