Как вставить значения из параллельных массивов в базу данных с помощью модуля Perl DBI?

Мне нужно вставить значения в базу данных, используя модуль Perl DBI. Я проанализировал файл, чтобы получить эти значения, и, следовательно, эти значения присутствуют в массивах, скажем, @array1, @array2, @array3, Я знаю, как вставить одно значение за раз, но не из массивов.

Я знаю, вставьте одно значение за раз:

$dbh = DBI->connect("dbi:Sybase:server=$Srv;database=$Db", "$user", "$passwd") or die "could not connect to database";
$query= "INSERT INTO table1 (id, name, address) VALUES (DEFAULT, tom, Park_Road)"; 
$sth = $dbh->prepare($query) or die "could not prepare statement\n";
$sth-> execute or die "could not execute statement\n $command\n";

Я не уверен, если у меня есть array1, содержащий идентификаторы, array2, содержащий имена, и array3, содержащий адрес, как мне вставить значения.

4 ответа

Решение

Поскольку у вас есть параллельные массивы, вы можете использовать advantange execute_array:

my $sth = $dbh->prepare('INSERT INTO table1 (id, name, address) VALUES (?, ?, ?)');
my $num_tuples_executed = $sth->execute_array(
    { ArrayTupleStatus => \my @tuple_status },
    \@ids,
    \@names,
    \@addresses,
);

Обратите внимание, что это усеченный (и слегка измененный) пример из документации. Вы определенно захотите проверить остальное, если решите использовать эту функцию.

Используйте заполнители.

Обновление: я только что понял, что у вас есть параллельные массивы. Это действительно не очень хороший способ работы с элементами данных, которые идут вместе. С этим предупреждением вы можете использовать List:: MoreUtils:: each_array:

#!/usr/bin/perl

use strict; use warnings;

use DBI;
use List::MoreUtils qw( each_array );

my $dbh = DBI->connect(
    "dbi:Sybase:server=$Srv;database=$Db", 
    $user, $passwd, 
) or die sprintf 'Could not connect to database: %s', DBI->errstr;

my $sth = $dbh->prepare(
    'INSERT INTO table1 (id, name, address) VALUES (?, ?, ?)'
) or die sprintf 'Could not prepare statement: %s', $dbh->errstr;

my @ids = qw( a b c);
my @names = qw( d e f );
my @addresses = qw( g h i);

my $it = each_array(@ids, @names, @address);
while ( my @data = $it->() ) {
    $sth->execute( @data )
        or die sprintf 'Could not execute statement: %s', $sth->errstr;
}

$dbh->commit
    or die sprintf 'Could not commit updates: %s', $dbh->errstr;

$dbh->disconnect;

Обратите внимание, что код не проверен.

Вы также можете прочитать FAQ: Что плохого в том, чтобы всегда заключать в кавычки "$vars"?,

Кроме того, учитывая, что единственный способ справиться с ошибкой - умереть, вы можете рассмотреть возможность указания { RaiseError => 1 } в connect вызов.

Как вы могли не быть уверены, что содержат ваши массивы? В любом случае, подход будет заключаться в итерации одного массива и при условии, что другие массивы имеют соответствующие значения и помещают их в оператор вставки.

Другой способ - использовать хеш в качестве промежуточного хранилища. IE:

my $hash = {};
foreach(@array1) {
  $hash->{id} = $array1[$_];
  $hash->{name} = $array2[$_];
  $hash->{address} = $array3[$_];
}
foreach( keys %$hash ) {
  $sql = "insert into table values(?,?,?)";
  $sth = $dbh->prepare($sql) or die;
  $sth->execute($hash->{id}, $hash->{name}, $hash->{address}) or die;
}

Хотя, опять же, это зависит от синхронизации трех массивов. Однако вы можете изменить это, чтобы сделать изменение значений или проверки или greps в других массивах в первом цикле через array1 (то есть: если ваши значения в array2 и array3 могут храниться как "NN-имя" и "NN-адрес", где NN является идентификатором из первого массива, и вам необходимо найти соответствующие значения и удалить NN- с помощью // регулярного выражения). Зависит от того, как ваши данные структурированы, хотя.

Еще одно замечание - проверить Class::DBI и посмотреть, может ли он обеспечить более приятный и более объектно-ориентированный способ ввода ваших данных.

Другие вопросы по тегам