我创建了一个Perl脚本,用于遍历数组(满足特定条件的客户名单),使用system()执行外部命令,然后在操作完成后更新每行中的字段
它适用于第一条记录(即外部命令执行,客户记录更新),但是当它到达第二条记录时,我收到此错误:
DBD :: mysql :: st fetchrow_array失败:在customer_update.pl上没有execute()的fetch()
通过一些谷歌搜索,我添加了$ sth-> finish();命令,无论我是否包含它(如图所示在循环内部,或之后直接)我仍然会得到相同的错误。
任何人都可以为我说明我在这里做错了什么吗?
这是一个摘录:
# PERL MYSQL CONNECT()
$dbh = DBI->connect('dbi:mysql:signups', $user, $pw)
or die "Connection Error: $DBI::errstr\n";
# DEFINE A MySQL QUERY
$myquery = "SELECT * FROM accounts WHERE field3 = false";
$sth = $dbh->prepare($myquery);
# EXECUTE THE QUERY
$sth->execute
or die "SQL Error: $DBI::errstr\n";
@records = $sth->rows;
print "Amount of new customers: @records\n\n";
while ( my ($field1, $field2, $field3) = $sth->fetchrow_array() ) {
#execute external command via system();
$update_customer_status = "UPDATE accounts SET field3=true WHERE id=$id";
$sth = $dbh->prepare($update_customer_status);
$sth->execute
or die "SQL Error: $DBI::errstr\n";
print "Customer record modified & MySQL updated accordingly\n\n";
$sth->finish();
}
答案 0 :(得分:4)
在循环中,覆盖要从中获取的句柄。使用其他变量。 (将$sth = ...;
更改为my $sth = ...;
即可。)当我们处于此状态时,让我们将prepare
移出循环。
my $sth_get = $dbh->prepare("SELECT * FROM accounts WHERE field3 = false");
my $sth_upd = $dbh->prepare("UPDATE accounts SET field3=true WHERE id = ?");
$sth_get->execute();
while ( my ($field1, $field2, $field3) = $sth_get->fetchrow_array() ) {
...
$sth_upd->execute($id);
}
答案 1 :(得分:4)
使用变量构建SQL语句然后准备()它会破坏准备的目的。您应该使用占位符?
而不是$id
构建SQL语句,prepare()它,然后执行($ id)它。实际上,你会让自己对SQL注入攻击持开放态度。
此外,您似乎没有使用warnings
和strict
pragma。这两行应该位于您编写的每个程序的顶部:
use warnings;
use strict;
他们将来会为你节省许多心痛和挫折。
答案 2 :(得分:1)
执行此行时,您正在踩踏$sth
变量...
$sth = $dbh->prepare($update_customer_status);
为什么不将$sth->fetchrow_array()
的结果保存到数组变量中。
有点像...
my @select_results_AoA = $sth->fetchrow_array();
...然后遍历数组...
for my @row ( @select_resilts_AoA ) {
......而不是......
while ( my ($field1, $field2, $field3) = $sth->fetchrow_array() ) {