RaiseError (PERL, DBI) 相当于 unixODBC C API?

发布于 2024-11-19 14:41:44 字数 2859 浏览 3 评论 0原文

我在 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;

并且isqlODBC 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白芷 2024-11-26 14:41:44

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文