我正在使用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层:外部错误:只有在命令结构空闲时才能调用此例程。
出了什么问题?
答案 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文档中记录了此行为:
如果应用程序没有取消结果集,只要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源代码,我无法在文档中找到确切的原因