RaiseError (PERL, DBI) эквивалент для UnixODBC C API? - PullRequest
0 голосов
/ 13 июля 2011

У меня проблема с выполнением некоторых хранимых процедур / функций в БД INFORMIX. Я пробовал с разными клиентами, и все они были одинаковыми - никто не обнаруживает ошибок при выполнении, вместо этого - возвращает пустые ответы. И это не работает для меня.

Наконец, я обнаружил, что PERL DBI имеет возможность установить RaiseError, что-то вроде:

{  PrintError => 0, RaiseError => 1 }

И это прекрасно работает. Но есть ли такой эквивалент (к сожалению, я ничего не нашел) для unixODBC C API lib?


Кроме того: я попробовал тот же запрос с isql, и он такой же! Нет ошибок, только пустой результат: \ Может быть, это может быть какой-то параметр, который должен быть настроен (в odbc.ini, я думаю ..)?


РЕДАКТИРОВАТЬ : Хорошо, вот еще несколько деталей:
Версия: unixODBC 2.3.0

CREATE FUNCTION "test".NOK_func_k() RETURNING LVARCHAR(1000);
set debug file to '/home/directory_does_not_exists/unknown.log';
trace off;
trace on;
trace off;
return 'result is set here';
END FUNCTION;

CREATE PROCEDURE "test".NOK_proc_k(pDummy SMALLINT)
set debug file to '/home/directory_does_not_exists/unknown.log';
trace off;
trace on;
LET pDummy = 2;
trace off;
END PROCEDURE;

И результаты isql и ODBC C API совпадают. Вот больше информации о C API:

Executing: execute procedure NOK_proc_k(1)
retcode = SQL_ERROR     SQL_SUCCEEDED( retcode ) = 0
--------------------------------------------------
Executing: execute function NOK_func_k()
retcode = SQL_SUCCESS       SQL_SUCCEEDED( retcode ) = 1
--------------------------------------------------
--------------------------------------------------
Executing: execute function NOK_proc_k(1)
retcode = SQL_ERROR     SQL_SUCCEEDED( retcode ) = 0
--------------------------------------------------
Executing: execute procedure NOK_func_k()
retcode = SQL_SUCCESS       SQL_SUCCEEDED( retcode ) = 1
--------------------------------------------------
--------------------------------------------------
Executing: call NOK_proc_k(1)
retcode = SQL_ERROR     SQL_SUCCEEDED( retcode ) = 0
--------------------------------------------------
Executing: call NOK_func_k()
retcode = SQL_SUCCESS       SQL_SUCCEEDED( retcode ) = 1

Все звонки на SQLMoreResults возврат SQL_NO_DATA, все SQLFetch возврат SQL_ERROR.

Сводка - все вызовы неправильных процедур в порядке - возвращается ошибка. Но если эта ошибка находится в сохраненной функции - ошибка не обнаружена; вместо этого - пустая строка возвращается. Outch!

SQL_SUCCESS_WITH_INFO - это , а не возвращается куда угодно. И это так для многих других ошибок (не все, конечно, это только пример здесь)


И даже больше! Процедура или функция как:

CREATE PROCEDURE "test".nok_proc_k_2() RETURNING LVARCHAR(1000);
DEFINE vNotDefined VARCHAR(10);
LET vNotDefined = current;
END PROCEDURE;

Не возвращает никаких ошибок, в то время как студия Aqua DB возвращает

Converted value does not fit into the allotted space

ОТВЕТ:

Я приму ответ bohica, так как он правильный и правильно отвечает по части PERL DBI. Кроме того, он действительно помог мне (хит с strace).

В любом случае, настоящего решения здесь нет. Я разместил его в соответствующем вопросе, который является более конкретным и изолированным для конкретного случая: Та же ошибка обнаружена в хранимой ** процедуре **, но не в хранимой ** функции **

1 Ответ

2 голосов
/ 13 июля 2011

Все, что делает RaiseError в Perl, это говорит о том, что когда DBD, такой как DBD :: ODBC, видит ошибку, DBI вызывает любые зарегистрированные обработчики ошибок и вызывает die с этой ошибкой (в зависимости от того, что вернул обработчик ошибок).DBD все еще должен сообщить об ошибке в DBI с помощью метода set_err.

Я предполагаю, что ваш Perl использовал DBD :: ODBC.DBD :: ODBC будет просто проверять состояние возврата каждого API-интерфейса ODBC, который он вызывает, и, если это SQL_SUCCESS_WITH_INFO, он вызывает DBI, set_err, говоря, что это предупреждение, и если это так!SQL_NO_DATA, что не всегда является ошибкой).

Если вы говорите, что ваш Perl умирает с ожидаемой ошибкой, а ваш код C - нет, то вы не должны проверять возврат ODBC API или, возможно, (поскольку вы упоминаетепроцедуры) вы не гарантируете, что вызываете SQLMoreResults в цикле после SQLExecute на SQL для вызова процедуры.Имейте в виду, что некоторые базы данных выполняют каждую вставку / выбор / обновление в процедуре по одной, и в ODBC вам нужно вызвать SQLMoreResults для перемещения по каждой из них.Если вы этого не сделаете, ваша процедура не была завершена, и, возможно, вы не нажали ошибку.

...