Ваш ERRORCODE
устанавливается в ноль, потому что это код выхода из подоболочки, в которой вы работаете SQL * Plus, viq обратные ссылки. Код выхода SQL * Plus - это 196, но вы не занимаетесь этим, и это не так просто сделать в heredoc. Вывод из процесса - это то, что вы захватываете - это не тот код выхода, это сообщение с запросом и ошибкой. И даже если бы вы могли его захватить, я не знаю, как бы вы отличали 196 от ошибки или от вашего фактического запроса.
Вы можете сделать что-то вроде выполнения запроса в блоке, который скрывает ошибку, и печатает либо значение по умолчанию, либо фактическое вычисленное значение, либо только посмотреть на последнюю строку вывода и попытаться ее интерпретировать; но вы все равно будете бороться с ним, показывая, что команда запускается. SQL * Plus имеет set echo off
, но это ничего не делает с интерактивным сеансом, который по-прежнему относится к перенаправлению ввода.
Другой путь заключается в создании файла сценария и временно хранить выход:
echo "
set pages 0
set trim on
set feed off
set echo off
whenever SQLERROR EXIT FAILURE
select 1/0 from dual;
--SELECT COUNT(*) FROM CNV_CHUNKS_PROC_STATUS;
exit 0;
" > /tmp/GetAmountOfChunks_$$.sql
sqlplus -s -l $CONSTR @/tmp/GetAmountOfChunks_$$.sql > /tmp/GetAmountOfChunks_$$.out
if [[ $? -eq 0 ]]; then
export CHUNK_AMOUNT=`cat /tmp/GetAmountOfChunks_$$.out`
else
# whatever you want to do on error; show output file? set default?
cat /tmp/GetAmountOfChunks_$$.out
fi
rm -f /tmp/GetAmountOfChunks_$$.sql /tmp/GetAmountOfChunks_$$.out
Это создает (процесс конкретного) .sql файла; выполняет запись записи (за вычетом инструкции, через set echo off
) в .out-файл; проверяет код выхода SQL * Plus; и если это нуль, получается результат из файла.
Как вы намекали, ссылаясь на SQL.SQLCODE
, чтобы обнаружить ошибку из вашего сценария оболочки, это опасно, поскольку вы можете получить ошибку, которая обертывается до нуля, поэтому я использовал общий FAILURE
. Если вам нужен реальный код ошибки, вы можете получить его из выходного файла.
Другой подход с использованием/SQL блок PL:
set -f
CHUNK_AMOUNT=`sqlplus -s $CONSTR <<SQL
set heading off;
set trim on;
set feed off;
whenever SQLERROR EXIT FAILURE;
set serveroutput on;
declare
chunk_amount number;
begin
select 1/0 into chunk_amount from dual;
--SELECT COUNT(*) INTO chunk_amount FROM CNV_CHUNKS_PROC_STATUS;
dbms_output.put_line(chunk_amount);
exception
when others then
dbms_output.put_line(sqlcode);
end;
/
exit 0
SQL
exit $?`
ERRORCODE=$?
Если/SQL пробегов блок PL затем ERRORCODE
будет равен нулю и CHUNK_AMOUNT
будет вычисленное значение, если оно успешно, или код SQL если он выдает исключение; так как это будет отрицательным (-1476 в вашем примере), вы можете проверить это, чтобы увидеть, ожидалось ли это, если вы ожидаете только положительных значений.
Если блок не может работать из-за синтаксической ошибки или неправильные учетные данные (обратите внимание на флаг -l
я пробралась в), то ERRORCODE
будет 1 и CHUNK_AMOUNT
будет иметь текст сообщения об ошибке, например, ERROR: ORA-12154: TNS:could not resolve the connect identifier...
или что-то на самом деле пошло не так.set -f
останавливает *
в сообщении об ошибке, которое расширяется в список файлов из текущего каталога.
Или еще проще и ближе к оригиналу:
set -f
CHUNK_AMOUNT=`sqlplus -s $CONSTR <<SQL
set heading off;
set trim on;
set feed off;
whenever SQLERROR EXIT FAILURE;
select 1/0 from dual;
--SELECT COUNT(*) FROM CNV_CHUNKS_PROC_STATUS;
exit 0
SQL
exit $?`
ERRORCODE=$?
и теперь ERRORCODE
является 0 в случае успеха и CHUNK_AMOUNT
имеет расчетное значение на какой-либо ошибке ERRORCODE
является 1, вы можете проверить, что непосредственно, и фактическая ошибка всегда находится в CHUNK_AMOUNT
- но только как строка, вы не получаете -1476 таким образом.
Предоставьте полный код, который вы использовали вместо всего лишь фрагмента ... Мы не можем понять, что происходит, и проблема может быть в той части кода, которую вы не разделили. – Camusensei