【问题标题】:RaiseError (PERL, DBI) equivalent for unixODBC C API?与 unixODBC C API 等效的 RaiseError(PERL、DBI)?
【发布时间】:2011-08-01 21:14:02
【问题描述】:

我在执行 INFORMIX DB 中的一些存储过程/函数时遇到问题。我尝试了不同的客户端,它们都是相同的——没有人在执行时检测到错误,而不是这个——返回空响应。这对我不起作用。

最后,我发现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;

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

总结 - 对错误过程的所有调用都很好 - 返回错误。但是如果这个错误在存储的 function 中 - 没有检测到错误;而不是这个 - 返回 EMPTY 字符串。出局!

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 的命中)。

无论如何,真正的解决方案不在这里。我已将其发布在相关问题中,该问题对特定案例更为具体和孤立:The same error is detected in stored **procedure**, but not in stored **function**

【问题讨论】:

  • 我不知道什么应该有效,什么无效。你所有的 procs 和 funcs 都被命名为 nok_something。调用 nok_func_k() 似乎返回成功 - 很好,但是执行过程 nok_func_k() 成功但没有这样的过程?另外“如果此错误出现在存储函数中-返回空字符串”-在哪里?如果函数/过程肯定出错,您不希望它们返回实际值。如果没有具体示例说明您拥有什么过程/功能、您如何调用它、发生了什么以及您期望什么,我将无法提供任何帮助。
  • @bohica - 我已经发布了NOK_func_kNOK_proc_k 正文。其中一个是过程,另一个是函数。我已经发布了它们是如何创建的。另外,我已经发布了它们的执行方式:Executing: .... + 结果。我不明白我应该发布什么更多信息.. NOK_proc_k 是内部错误的程序。并且检测到错误,所以我不希望它返回任何东西。正如你所引用的那样——“如果这个错误出现在存储函数中——返回空字符串”——看,我说的是函数,所以,我的意思是nok_func_k
  • @bohica - 一直成功的是nok_func_k,它是一个函数,而不是一个过程。但它与过程 (NOK_proc_k) 具有相同的主体,它只是声明为函数并返回一个字符串。请注意NOK_func_k 在末尾如何返回:return 'result is set here';。由于未检测到错误,SQLExecute 返回SQL_SUCCESS,返回的字符串不是"result is set here",而是""。哪一部分我不解释好吗..? :\
  • 另外,从Aqua Data Studio 执行call NOK_func_k() 并从PERL DBI 执行同样的操作,检测到错误:Cannot open DEBUG file for SPL routine trace. ..
  • @bohica - 你可以看到我的相关问题 - stackoverflow.com/questions/6843403/… 它更清楚(或者至少我希望如此),它是孤立的,没有不必要的信息。

标签: c perl dbi unixodbc


【解决方案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 返回,或者(因为您提到了过程)您没有确保在循环中调用 SQLMoreResults在 SQL 上的 SQLExecute 之后调用该过程。请记住,某些数据库一次在一个过程中执行每个插入/选择/更新,而在 ODBC 中,您需要调用 SQLMoreResults 来遍历每个过程。如果您不这样做,您的程序还没有完成,因此您可能没有遇到错误。

【讨论】:

  • 好吧,我尝试了 SQLExecDirectSQLExecute 并且都返回 SQL_SUCCESS :( 所以,SQL_SUCCEEDED(SQLExecute( stmt )) 分别返回 true :\ 这让我担心,但我没有尝试过SQLMoreResults 还没有。
  • 有趣的是,用isql 执行同样的操作不会再给我任何错误。那么,我想这可能是一些可配置的选项?
  • isql 不调用 SQLMoreResults
  • 如果您愿意,我可以向您展示 DBD::ODBC 在 ODBC 方面的作用。只需设置 DBI_TRACE=15=x.log 并将其导出,然后重新运行您的 Perl。你会得到负载,这会给你一个线索。或者,假设您使用的是 unixODBC 驱动程序管理器,您可以在其中启用对所有 ODBC 调用的跟踪。
  • "isql 不调用 SQLMoreResults" - 是的
猜你喜欢
  • 2011-03-26
  • 1970-01-01
  • 2013-06-07
  • 2010-12-27
  • 2010-12-30
  • 1970-01-01
  • 2023-03-03
  • 2010-12-25
  • 2014-12-24
相关资源
最近更新 更多