RaiseError (PERL, DBI) 相当于 unixODBC C API?
我在 INFORMIX DB 中执行某些存储过程/函数时遇到问题。我尝试使用不同的客户端,它们都是相同的 - 没有人检测到执行时的错误,而不是返回空响应。这对我不起作用。
最后,我发现 PERL DBI 可以选择设置 RaiseError,例如:
{ PrintError => 0, RaiseError => 1 }
这非常完美。但是对于 unixODBC C API
库是否有这样的等效项(不幸的是,我找不到任何东西)?
另外:我用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
。
摘要 - 所有对错误过程的调用都很好 - 返回错误。但是,如果此错误出现在存储的函数中 - 则不会检测到错误;而不是这个 - 返回空字符串。哎呀!
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
的成功)。
无论如何,真正的解决办法并不在这里。我已将其发布在相关问题中,该问题对于特定情况更加具体和孤立: 在存储的**过程**中检测到相同的错误,但在存储的**函数**中没有检测到
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**
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Perl 中的 RaiseError 所做的就是说,当 DBD(例如 DBD::ODBC)看到错误时,DBI 将调用任何已注册的错误处理程序,并使用该错误调用 die(取决于错误处理程序返回的内容)。仍然由 DBD 通过 set_err 方法向 DBI 发出错误信号。
我猜你的 Perl 使用的是 DBD::ODBC。 DBD::ODBC 将简单地检查它调用的每个 ODBC API 的返回状态,如果是 SQL_SUCCESS_WITH_INFO,它会调用 DBI set_err 表示这是一个警告,如果是 !SQL_SUCCEEDED,它会调用 set_err 表示存在错误(有一些例外,例如SQL_NO_DATA 这并不总是错误)。
如果你说你的 Perl 因你期望的错误而死掉,但你的 C 代码没有,那么你一定不能检查 ODBC API 返回,或者也许(因为你提到了过程)你不能确保在 SQLExecute 之后循环调用 SQLMoreResults调用该过程的 SQL。请记住,某些数据库在过程中一次执行一个插入/选择/更新,而在 ODBC 中,您需要调用 SQLMoreResults 来遍历每个插入/选择/更新。如果您不这样做,您的过程尚未完成,因此您可能不会遇到错误。
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.