为啥 Perl DBI 抱怨“在未打开的游标上尝试获取”?
Posted
技术标签:
【中文标题】为啥 Perl DBI 抱怨“在未打开的游标上尝试获取”?【英文标题】:Why does Perl's DBI complain about "Fetch attempted on unopen cursor"?为什么 Perl DBI 抱怨“在未打开的游标上尝试获取”? 【发布时间】:2009-05-07 13:42:40 【问题描述】:这是我的脚本:
$db_handle=DBI->connect("$dbstr", "", "",
RaiseError => 0, AutoCommit => 0, PrintError => 1)
|| die "Connect error: $DBI::errstr" ;
$result=$db_handle->selectrow_array("set isolation to dirty read");
注意:$dbstr
是一个有效的数据库名称。
我不是数据库程序员。我做错了什么导致 Perl 脚本失败:
DBD::Informix::db selectrow_array 失败:SQL:-400:在未打开的游标上尝试获取。
如果我编写一个简单的脚本来连接数据库$dbstr
并显示表格内容,它可以正常工作,但上面的代码不起作用。
【问题讨论】:
请注意,有文档记录的地方可以寻求对 DBD::Informix 的支持(这不是其中之一,但在创建 DBD::Informix 的最后一个版本时它并不存在) .请注意,更重要的是,有 LOT 的版本信息需要回答更复杂的问题,包括以下版本:Perl、DBI、DBD::Informix、ESQL/C(或CSDK)、IDS(或其他 Informix DBMS)、平台,有时甚至是编译器。这些要求在源文件中列出。甚至还提供了一个脚本来收集其中的大部分内容 - InformixTechSupport。 【参考方案1】:selectrow_array
方法旨在与返回结果集的语句一起使用。 SET ISOLATION 语句不是这样的语句 - 它会失败。
错误 -400 是否是最好的错误有点值得商榷 - 有时我会看看是否可以做任何事情。但是,IIRC,selectrow_array
方法是由 DBI 而不是 DBD::Informix 提供的,因此 DBI 从较低级别的原语构建它。因此,这些原语无法提供更高级别函数可以提供的验证,因为它们也必须单独工作。
编写该代码的正确方法是:
$db_handle->do("set isolation mode to dirty read");
【讨论】:
【参考方案2】:您正在执行的语句中没有结果可供您获取:
set isolation to dirty read
所以selectrow_array()
是错误的调用方法。请改用$dbh->do(...):
$db_handle->do('set isolation to dirty read');
下面是对 -400 错误的详细解释:
-400 在未打开的光标上尝试获取。
此 FETCH 语句命名一个从未打开过的游标或 被关闭。查看程序逻辑,并检查它是否会打开 光标在此点之前,而不是意外关闭它。除非光标 被声明为 WITH HOLD,它由 COMMIT WORK 自动关闭或 ROLLBACK WORK 语句。
正如 Jonathan 所指出的,这可能不是最明显的错误,但一旦您了解了发生的情况,它确实是有道理的。
【讨论】:
【参考方案3】:请阅读DBD::Informix 的文档,尤其是“CONNECTING_TO_A_DATABASE”部分。连接到 Informix 数据库所需的最少代码似乎是:
$dbh = DBI->connect("dbi:Informix:$database");
因此,您必须提供的不仅仅是数据库的名称。
【讨论】:
问题说连接正常 - 因此他们提供的不仅仅是数据库名称。不过,DBD::Informix 文档的外部参考仍然有用。【参考方案4】:set isolation to dirty read
不是查询,而是语句。只有查询进入selectrow_array
。你需要do
:
#!usr/bin/perl
use strict;
use warnings;
use DBI;
my $dbi = "dbi:Informix:dbname";
my $dbh = DBI->connect(
$dbi,
"",
"",
RaiseError => 1,
AutoCommit => 0,
PrintError => 1,
ChopBlanks => 1,
) or die "Connect error: $DBI::errstr";
my $result = $dbh->do("set isolation to dirty read");
$dbh->disconnect;
【讨论】:
以上是关于为啥 Perl DBI 抱怨“在未打开的游标上尝试获取”?的主要内容,如果未能解决你的问题,请参考以下文章
当跟踪中的语句返回 1 时,为啥 perl DBI 返回 0 行
为啥 Perl 的 GD::Graph 抱怨“无效数据集”?