RaiseError (PERL, DBI) equivalent for unixODBC C API?

回眸只為那壹抹淺笑 提交于 2019-12-25 02:26:01

问题


I have a problem executing some stored procedures/functions in INFORMIX DB. I tried with different clients and they were all the same - no one detects errors on executing, instead of this - return empty responses. And this does not work for me.

Finally, I found that PERL DBI has the option to set RaiseError, something like:

{  PrintError => 0, RaiseError => 1 }

And this works perfect. But is there such equivalent (I couldn't find anything, unfortunately) for the unixODBC C API lib?


In addition: I tried the same query with isql and it's the same! No errors, just empty result :\ Maybe it could be some option, that should be configured (in odbc.ini, I guess..) ?


EDIT: Okay, here are some more details:
Version: 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;

And the results from isql and ODBC C API are the same. Here's more info about the 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

All calls to SQLMoreResults return SQL_NO_DATA, all SQLFetch return SQL_ERROR.

Summary - all calls to wrong procedures are fine - error is returned. But if this error is in stored function - no error is detected; instead of this - EMPTY string is returned. Outch!

SQL_SUCCESS_WITH_INFO is not returned anywhere. And it's like this for many other errors (not all, of course, that's just an example here)


And even more! Procedure or function like:

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

Does not return any error, while a Aqua DB studio returns

Converted value does not fit into the allotted space

ANSWER:

I'll accept bohica'S answer, as it's correct and it answers right about the PERL DBI part. Also, he really helped me (the hit with strace).

Anyway, the real solution is not here. I have posted it in the related question, that is more specific and isolated about the particular case: The same error is detected in stored **procedure**, but not in stored **function**


回答1:


All that RaiseError in Perl does is say that when a DBD, like DBD::ODBC sees an error DBI will call any registered error handlers and call die with that error (depending on what the error handler returned). It is still up to the DBD to signal the error to DBI via set_err method.

I presume your Perl was using DBD::ODBC. DBD::ODBC will simply check the return status of every ODBC API it calls and if it is SQL_SUCCESS_WITH_INFO it calls DBIs set_err saying it is a warning and if it is !SQL_SUCCEEDED it calls set_err saying there is an error (there are some exceptions like SQL_NO_DATA which is not always an error).

If you are saying your Perl dies with the error you are expecting but your C code does not then you must not be checking an ODBC API return or perhaps (since you mention procedures) you are not ensuring you call SQLMoreResults in a loop after SQLExecute on the SQL to call the procedure. Bear in mind some databases execute each insert/select/update in a procedure one at a time and in ODBC you need to call SQLMoreResults to move through each one. If you don't do that your procedure had not completed and hence you may not have hit the error.



来源:https://stackoverflow.com/questions/6679261/raiseerror-perl-dbi-equivalent-for-unixodbc-c-api

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!