Как вставить значения из параллельных массивов в базу данных с помощью модуля 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 и посмотреть, может ли он обеспечить более приятный и более объектно-ориентированный способ ввода ваших данных.