在Perl循环失败中更新MySQL(fetchrow_array)

时间:2013-09-09 01:02:24

标签: mysql perl

我创建了一个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();
}

3 个答案:

答案 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注入攻击持开放态度。

此外,您似乎没有使用warningsstrict 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() ) {