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

Мне нужно вставить значения в базу данных, используя модуль 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 ]

4 голосов
/ 19 ноября 2009

Так как у вас есть параллельные массивы, вы можете использовать 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,
);

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

2 голосов
/ 18 ноября 2009

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

Обновление: Я только что понял, что у вас есть параллельные массивы. Это действительно не очень хороший способ работы с элементами данных, которые идут вместе. С этим предупреждением вы можете использовать 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.

0 голосов
/ 18 ноября 2009

Другой способ - использовать хеш в качестве промежуточного хранилища. 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-name» и «NN-address», где NN это идентификатор из первого массива, и вам нужно найти соответствующие значения и удалить NN- с помощью // регулярного выражения). Хотя зависит от того, как структурированы ваши данные.

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

0 голосов
/ 18 ноября 2009

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

...