Sybase::CTlib 的 ct_results() 和 ct_cmd_drop() 错误

发布于 2024-09-28 17:37:23 字数 766 浏览 4 评论 0原文

我正在使用 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;
}

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

我收到错误:

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

打开客户端消息:
消息编号:LAYER = (1) ORIGIN = (1) SEVERITY = (1) NUMBER = (159)
消息字符串:ct_cmd_drop():用户 API 层:外部错误:仅当命令结构空闲时才能调用此例程。

出了什么问题?

I'm using Sybase::CTlib to query a Sybase server. However when I execute the following:

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;
}

My query returns exactly one value. Thats why I'm reading into one variable.

I'm getting errors:

Open Client Message:
Message number: LAYER = (1) ORIGIN = (1) SEVERITY = (1) NUMBER = (163)
Message String: ct_results(): user api layer: external error: This routine cannot be called until all fetchable results have been completely processed.

Open Client Message:
Message number: LAYER = (1) ORIGIN = (1) SEVERITY = (1) NUMBER = (159)
Message String: ct_cmd_drop(): user api layer: external error: This routine can be called only if the command structure is idle.

What's going wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

樱桃奶球 2024-10-05 17:37:24

即使您的 SQL 返回一行,您也不能仅调用 ct_fetch 一次(正如您的代码所做的那样)。您必须循环调用它直到 false。

brian d foy的方法似乎是最简洁的解决方案(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< /a>

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

最简单的方法是在一个循环中,当 ct_fetch 无法返回 CS_SUCCEED 或 CS_ROW_FAIL 时终止。循环终止后,应用程序可以针对 ct_fetch 的最终返回代码使用 switch 类型语句来找出导致终止的原因。

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

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

我对其原因的未经明确的猜测是,CTLib 内部有一些“结果集已完成”标志设置为 false,并且直到 ct_fetch 发现结果集中不再有行为止,它不会重新设置为 true (基本上,布莱恩·D·福伊所说的); CTLib 代码的其余部分检查该标志,并在该标志为 false 时输出错误 163。

如果不查看实际的 CTLib 源代码,我无法 100% 确认这一点,我无法在文档中找到确切的原因

You can not call ct_fetch only once (as your code does), even if your SQL returns one row. You must call it in a loop till false.

brian d foy's approach seems to be the most consise solution (1 while (my @data = $dbh->ct_fetch); so I won't bother providing alternatives. What I will provide is the documentation showing why your code failed.

This behavior is documented in SyBooks docs for ct_fetch:

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

If an application does not cancel a result set, it must completely process the result set by calling ct_fetch as long as ct_fetch continues to indicate that rows are available.

The simplest way to do this is in a loop that terminates when ct_fetch fails to return either CS_SUCCEED or CS_ROW_FAIL. After the loop terminates, an application can use a switch-type statement against ct_fetch’s final return code to find out what caused the termination.

If a result set contains zero rows, an application’s first ct_fetch call will return CS_END_DATA.

Note: An application must call ct_fetch in a loop even if a result set contains only a single row. An application must call ct_fetch until it fails to return either CS_SUCCEED or CS_ROW_FAIL.

My un-edicated guess as to the reason is that there's some "result set completed" flag set internally in CTLib to false and it doesn't get re-set to true till ct_fetch finds that no more rows are left in the result set (basically, what brian d foy said); and the rest of CTLib code checks that flag and errors out with error 163 when the flag is false.

I can't confirm that 100% without looking at actual CTLib source code, I wasn't able to find exact reason in the documentation

素衣风尘叹 2024-10-05 17:37:24

当您再次调用 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
}

What happens when you call ct_fetch again? I don't use Sybase, but from looking at the docs it looks like the module expects you to make an additional call, at which point it realizes it has fetched all the data and shuts down whatever it is tracking internally.

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