2

我在 Perl 中有 3 个不同的数组(即 A、B 和 C)。现在,我在 mysql 中有一个表,它也有 3 个字段。

我想要做的是在mysql表的第一个字段中获取数组A的所有内容,在第二个字段中获取数组B的内容,依此类推。我尝试使用 foreach 循环执行此操作,但它适用于第一个数组,但不会为第二个和第三个数组插入任何内容。

使用的代码如下:

foreach my $a (@a) {

    my $sql = "insert into es(a) VALUES(\"$a\")";
    my $sth = $dbh->prepare($sql);
    $sth->execute or die "SQL Error: $DBI::errstr\n";
}


foreach my $b (@b) {

    my $sql = "insert into es(b) VALUES(\"$b\")";
    my $sth = $dbh->prepare($sql);
    $sth->execute or die "SQL Error: $DBI::errstr\n";

}

第三个也是如此。表的 a 列已正确填充,但表中的 b 列和 c 列没有数据。我究竟做错了什么。

4

1 回答 1

6

我猜你对关系数据库不是很熟悉。你所做的是:

  1. 迭代@a
  2. 为每个项目准备一个新的声明@a
  3. 每个插入添加一行,仅包含其中的a值;这意味着:
    • 您为每个项目创建一个数据集@a
    • bcNULL

现在你也这样做@b@c。那不是很有效。

DBI旨在为您提供帮助。您应该考虑以下规则(指南):

  • 始终使用 DBI 的quote方法或更好的占位符。这样可以省去您自己添加引号的麻烦。
  • 如果有一个循环和几个INSERTs 或UPDATEs,请始终prepare将您的查询放在循环之外,而将execute其放在循环中。

那我们来看看你的问题。我假设@a,@b并且@c都具有相同数量的项目,并且您希望 , 和每个索引一行@a@b@c。因此,如果您有以下数据:

my @a = (1, 2, 3);
my @b = qw(foo bar baz)
my @c = (999, 998, 997);

我敢打赌,您希望它在数据库中看起来像这样:

a b   c
1 foo 999
2 bar 998
3 baz 997

因此,我们需要将您的三个INSERTs 合并为一个语句。这可以通过一次迭代所有这些来完成。我们可以使用List::MoreUtilseach_array中的函数来为我们处理迭代。我们还将上面的指南添加到代码中。

use List::MoreUtils qw(each_array);
my $dbh = DBI->connect(); # connect to db here

# prepare the INSERT statement once
my $sth_insert = $dbh->prepare('INSERT INTO es SET a=?, b=?, c=?')
  or die $dbh->errstr;

# create the array iterator
my $ea = each_array(@a, @b, @c);
# iterate over all three arrays step by step
while ( my ($val_a, $val_b, $val_c) = $ea->() ) {
  $sth_insert->execute($val_a, $val_b, $val_c) or die $dbh->errstr;
}
于 2012-09-21T10:47:53.267 回答