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

Я не уверен, что у меня есть массив1, содержащий идентификаторы, массив2, содержащий имена, и массив3, содержащий адрес, как мне вставить значения.


person shubster    schedule 18.11.2009    source источник
comment
Параллельные массивы на самом деле не очень хороший способ делать что-то.   -  person hobbs    schedule 18.11.2009


Ответы (4)


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

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

person bish    schedule 18.11.2009
comment
Да, конечно ... Я достиг своего лимита голосов на день, но я проголосую за этот ответ. - person Sinan Ünür; 19.11.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.

person Sinan Ünür    schedule 18.11.2009

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

person ennuikiller    schedule 18.11.2009
comment
@ennuikiller: я знаю, что содержит мой массив, но не знаю, как вставлять значения в базу данных. - person shubster; 18.11.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 в других массивах в первом цикле через массив1 (т.е.: если ваши значения в массиве2 и массиве3 могут храниться как «NN-имя» и «NN-адрес», где NN это идентификатор из первого массива, и вам нужно найти соответствующие значения и удалить NN- с as// regex). Хотя зависит от того, как структурированы ваши данные.

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

person Arcterex    schedule 18.11.2009