【问题标题】:Update MySQL within Perl loop failing (fetchrow_array)在 Perl 循环中更新 MySQL 失败 (fetchrow_array)
【发布时间】:2013-09-09 15:12:36
【问题描述】:

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

【问题讨论】:

  • 你要调用的外部命令是什么?通常不会执行select,然后通过单独的update 命令更新每个结果,此时您可以轻松地将select 语句中使用的where 子句移动到update 语句的where 子句。
  • finish 用于当您不想遍历 SELECT 返回的其余结果时。 UPDATE 之后就没用了

标签: mysql perl


【解决方案1】:

使用变量构建 SQL 语句然后对其进行prepare() 违背了prepare 的目的。您应该使用占位符? 而不是$id 构建SQL 语句,准备()它,然后执行($id)它。事实上,您让自己容易受到 SQL 注入攻击。

另外,您似乎没有使用warningsstrict 编译指示。这两行应该在您编写的每个程序的顶部:

use warnings;
use strict;

他们会在未来为你省去很多心痛和挫折。

【讨论】:

    【解决方案2】:

    在您的循环中,您覆盖了您从中获取的句柄。使用不同的变量。 (将$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);
    }
    

    【讨论】:

      【解决方案3】:

      当您执行此行时,您正在踩踏 $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() ) {
      

      【讨论】:

      • 正确的问题,但您的解决方案根本没有帮助。也许您打算使用selectall_arrayref
      • @ikegami 是的,selectall_arrayref 会更合适。谢谢。
      猜你喜欢
      • 2013-09-19
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 2013-01-28
      • 2012-11-22
      • 2023-03-26
      • 1970-01-01
      • 2018-03-30
      相关资源
      最近更新 更多