问题
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