首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Apache抱怨我的mod_perl程序“断开连接使一个活动语句句柄无效”?

为什么Apache抱怨我的mod_perl程序“断开连接使一个活动语句句柄无效”?
EN

Stack Overflow用户
提问于 2009-02-12 14:39:06
回答 3查看 13.5K关注 0票数 9

断开连接使一个活动语句句柄无效(要么销毁语句句柄,要么在断开连接之前对它们调用finish )

从MySQL获取数据的以下代码被成功执行,但将导致Apache在其错误日志中生成上述消息:

代码语言:javascript
复制
my $driver   = "mysql";
my $server   = "localhost:3306";
my $database = "test";
my $url      = "DBI:$driver:$database:$server";
my $user     = "apache";
my $password = "";

#Connect to database
my $db_handle = DBI->connect( $url, $user, $password ) 
    or die $DBI::errstr;

#SQL query to execute
my $sql = "SELECT * FROM tests WHERE id=?";

#Prepare SQL query
my $statement = $db_handle->prepare($sql)
        or die "Couldn't prepare query '$sql': $DBI::errstr\n";

#Execute SQL Query
$statement->execute($idFromSomewhere)
    or die "Couldn't execute query '$sql': $DBI::errstr\n";

#Get query results as hash
my $results = $statement->fetchall_hashref('id');

$db_handle->disconnect();
  • 忽略上述错误/警告会有什么可怕的后果吗?代码运行了一周,没有任何不良影响。
  • 代码有什么问题吗?还是这只是一个无害的警告?

编辑

代码通过mod_perl执行。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-02-12 14:43:33

您应该在$statement->finish();之前调用$db_handle->disconnnect();

通常您不需要调用finish,除非您没有得到所有的行。如果使用fetchrow_array在循环中获得所有结果,则除非中止循环,否则不会在结束时调用finish。

我不知道为什么MySQL驱动程序在fetchall_hashref之后没有完成语句。该手册建议您的查询可能由于以下错误而中止:

如果发生错误,fetchall_hashref将返回到目前为止获取的数据,该数据可能为空。您应该检查$ the >err(或使用RaiseError属性),以发现数据是否已完成或由于错误而被截断。

票数 13
EN

Stack Overflow用户

发布于 2009-02-12 14:54:38

这是由仍处于活动状态的句柄造成的。通常情况下,它应该关闭自己,但您似乎并没有从它获取所有的数据。来自DBI上的perldoc

当从SELECT语句中获取所有数据时,驱动程序将自动为您调用finish。因此,通常不需要显式调用它,除非您知道没有从语句句柄获取所有数据。最常见的例子是当您只想获取一行时,但是在这种情况下,selectrow_*方法通常更好。在每个fetch循环之后添加要完成的调用是一个常见的错误,不要这样做,它可能掩盖真正的问题,如未捕获错误。

票数 3
EN

Stack Overflow用户

发布于 2012-12-03 21:58:30

虽然可能不是您收到此警告的原因(这正是手册声称的那样),但在略有不同的情况下,我也经历了相同的警告,我想在这里提出它,而不是自己提出问题。

如果您执行一个查询来获取一些行,您可能会发现自己在这个场景中--但只是为了知道是否有符合的行。在我的情况下,如果找到匹配项,我们将更新行,否则插入行。

因为没有对找到的行进行任何处理,所以我认为这构成了一种情况,在这种情况下,遵循警告的领导是合适的。因此,在断开连接之前,我在选择处理程序上调用finish()

免责声明:作为DBI的新成员,有可能有更好的方法。我本来会使用->do(),除非文献资料指出,在反复执行时不应该使用它--由于某些原因,也不鼓励SELECT语句!

下面是一些perl伪代码,显示了我在上面的内容:

代码语言:javascript
复制
$selectHandler = $dbh->prepare($queryString) or die "Cannot prepare: ".$dbh->errstr;
#Loop through a list of keys to check existence {
    $selectHandler.execute($uniqueID);
    $found = 0;
    $found = $selectHandler->fetch();
    if (!$found) {
        # Do an insert of $uniqueID
    } else {
        # Do an update of $uniqueID
    }
#}
# Having not done anything with the selectHandler's result (when rows were 
# found) close it now that the loop is complete
$selectHandler->finish(); # we don't need you any more select handler!
$dbh->disconnect or warn "Disconnection error: $DBI::errstr\n";

希望这对其他人有帮助,如果我误导任何人,请随时纠正我的做法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/541542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档