我使用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;
}我的查询正好返回一个值。这就是为什么我要读到一个变量。
我在犯错误:
打开客户端消息: 消息号:层= (1)源= (1)严重性= (1)编号= (163) 消息字符串: ct_results():user层:外部错误:在所有可获取的结果被完全处理之前,不能调用这个例程。 打开客户端消息: 消息号:层= (1)原产地= (1)严重性= (1)数字= (159) 消息字符串: ct_cmd_drop():user层:外部错误:只有当命令结构空闲时才能调用此例程。
出什么问题了?
发布于 2010-10-26 04:25:55
您不能只调用ct_fetch一次(正如代码所做的那样),即使您的SQL返回一行。你必须在循环中调用它,直到误。
布赖恩·福伊的方法似乎是最深思熟虑的解决方案(1 while (my @data = $dbh->ct_fetch); ),因此我不会费心提供替代方案。我要提供的是说明为什么您的代码失败的文档。
这种行为记录在SyBooks文档中,用于ct_fetch:
12.5.1.ctref/html/ctref/X65123.htm
如果应用程序不取消结果集,它必须通过调用完全处理结果集,只要ct_fetch继续指示行是可用的。 最简单的方法是在循环中完成,当ct_fetch不能返回CS_SUCCEED或CS_ROW_FAIL时终止。循环结束后,应用程序可以对ct_fetch的最后返回代码使用开关类型语句来找出导致终止的原因。 如果结果集包含零行,则应用程序的第一个ct_fetch调用将返回CS_END_DATA。 注意:应用程序必须在循环中调用ct_fetch,即使结果集只包含一行。应用程序必须调用ct_fetch,直到它无法返回CS_SUCCEED或CS_ROW_FAIL为止。
关于原因,我的猜测是,在CTLib内部有一些“结果集已完成”的标志集设置为false,并且在ct_fetch发现结果集中没有剩下的行之前,它不会重新设置为true (基本上,brian是这么说的);当标志为false时,CTLib代码会用错误163检查该标志和错误。
如果不查看实际的CTLib源代码,我无法确定100%,我无法在文档中找到确切的原因
发布于 2010-10-25 23:27:01
当您再次调用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
}https://stackoverflow.com/questions/4012496
复制相似问题