断开连接使一个活动语句句柄无效(要么销毁语句句柄,要么在断开连接之前对它们调用finish )
从MySQL获取数据的以下代码被成功执行,但将导致Apache在其错误日志中生成上述消息:
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执行。
发布于 2009-02-12 14:43:33
您应该在$statement->finish();之前调用$db_handle->disconnnect();。
通常您不需要调用finish,除非您没有得到所有的行。如果使用fetchrow_array在循环中获得所有结果,则除非中止循环,否则不会在结束时调用finish。
我不知道为什么MySQL驱动程序在fetchall_hashref之后没有完成语句。该手册建议您的查询可能由于以下错误而中止:
如果发生错误,fetchall_hashref将返回到目前为止获取的数据,该数据可能为空。您应该检查$ the >err(或使用RaiseError属性),以发现数据是否已完成或由于错误而被截断。
发布于 2009-02-12 14:54:38
这是由仍处于活动状态的句柄造成的。通常情况下,它应该关闭自己,但您似乎并没有从它获取所有的数据。来自DBI上的perldoc:
当从SELECT语句中获取所有数据时,驱动程序将自动为您调用finish。因此,通常不需要显式调用它,除非您知道没有从语句句柄获取所有数据。最常见的例子是当您只想获取一行时,但是在这种情况下,selectrow_*方法通常更好。在每个fetch循环之后添加要完成的调用是一个常见的错误,不要这样做,它可能掩盖真正的问题,如未捕获错误。
发布于 2012-12-03 21:58:30
虽然可能不是您收到此警告的原因(这正是手册声称的那样),但在略有不同的情况下,我也经历了相同的警告,我想在这里提出它,而不是自己提出问题。
如果您执行一个查询来获取一些行,您可能会发现自己在这个场景中--但只是为了知道是否有符合的行。在我的情况下,如果找到匹配项,我们将更新行,否则插入行。
因为没有对找到的行进行任何处理,所以我认为这构成了一种情况,在这种情况下,遵循警告的领导是合适的。因此,在断开连接之前,我在选择处理程序上调用finish()。
免责声明:作为DBI的新成员,有可能有更好的方法。我本来会使用->do(),除非文献资料指出,在反复执行时不应该使用它--由于某些原因,也不鼓励SELECT语句!
下面是一些perl伪代码,显示了我在上面的内容:
$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";希望这对其他人有帮助,如果我误导任何人,请随时纠正我的做法。
https://stackoverflow.com/questions/541542
复制相似问题