Sybase :: CTlib发生ct_results()和ct_cmd_drop()错误

时间:2010-10-25 07:11:12

标签: perl sybase dbi

我正在使用Sybase::CTlib来查询Sybase服务器。但是当我执行以下操作时:

while( $dbr->ct_results($restype) == CS_SUCCEED ) {
    if( $restype == CS_CMD_FAIL ) {
    warn "Update Check Failed...";
    next;
    }
    next unless $dbr->ct_fetchable($restype);
    $ts = $dbr->ct_fetch;
}

我的查询只返回一个值。这就是为什么我要读一个变量。

我收到错误:

  

Open Client Message:
  消息编号:LAYER =(1)ORIGIN =(1)SEVERITY =(1)NUMBER =(163)
  消息字符串:ct_results():用户api层:外部错误:在完全处理完所有可获取结果之前,无法调用此例程。

     

Open Client Message:
  消息编号:LAYER =(1)ORIGIN =(1)SEVERITY =(1)NUMBER =(159)
  消息字符串:ct_cmd_drop():用户api层:外部错误:只有在命令结构空闲时才能调用此例程。

出了什么问题?

2 个答案:

答案 0 :(得分:0)

再次致电ct_fetch会怎样?我不使用Sybase,但从查看文档看起来模块希望你进行额外的调用,此时它意识到它已经获取了所有数据并关闭了内部跟踪的任何内容。

while( $dbr->ct_results($restype) == CS_SUCCEED ) {
    if( $restype == CS_CMD_FAIL ) {
        warn "Update Check Failed...";
        next;
        }
    next unless $dbr->ct_fetchable($restype);
    $ts = $dbr->ct_fetch;
    1 while(my @data = $dbh->ct_fetch); # discard the rest
}

答案 1 :(得分:0)

即使您的SQL返回一行,也不能只调用一次ct_fetch(就像您的代码一样)。你必须在循环中调用它直到错误。

brian d foy's approach似乎是最简洁的解决方案(1 while (my @data = $dbh->ct_fetch);所以我不打算提供替代方案。我将提供的文档说明您的代码失败的原因。

在ct_fetch的SyBooks文档中记录了此行为:

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sdk_12.5.1.ctref/html/ctref/X65123.htm

  

如果应用程序没有取消结果集,只要ct_fetch继续指示行可用,它必须通过调用ct_fetch完全处理结果集。      

执行此操作的最简单方法是在循环中,当ct_fetch无法返回CS_SUCCEED或CS_ROW_FAIL时终止。在循环终止后,应用程序可以对ct_fetch的最终返回码使用switch-type语句来找出导致终止的原因。

     

如果结果集包含零行,则应用程序的第一个ct_fetch调用将返回CS_END_DATA。

     

注意:即使结果集只包含一行,应用程序也必须在循环中调用ct_fetch。应用程序必须调用ct_fetch,直到它无法返回CS_SUCCEED或CS_ROW_FAIL。

我的原因是没有法律的猜测是因为CTLib内部设置了一些“结果集已完成”标志为false,并且在ct_fetch发现没有更多行留在其中之前它不会重新设置为true。结果集(基本上,brian d foy所说的);当标志为假时,CTLib代码的其余部分检查标记和错误,错误163。

我无法确认100%没有查看实际的CTLib源代码,我无法在文档中找到确切的原因