0

dbh1 と dbh2 の 2 つのサーバーがあり、dbh1 にクエリを実行し、fetchall_arrayref メソッドを介してデータを取得します。クエリを実行したら、dbh1 からの出力をサーバー dbh2 の一時テーブルに挿入します。

両方のサーバーへのアクセスを同時に確立でき、両方からデータを取得できます。1. dbh1 からデータをプルします。

while($row = shift(@$rowcache) || shift(@{$rowcache=$sth1->fetchall_arrayref(undef, $max_rows)})) {
        #call to sub insert2tempData
        &insert2tempData(values @{$row});
}

2. 次に、dbh2 に挿入クエリがあります。

    INSERT INTO ##population (someid, Type, anotherid)
    VALUES ('123123', 'blah', '634234'); 

質問: dbh1 からの fetchall_arrayref の一括結果をサーバー dbh2 の一時テーブルに (個々のレコードをループせずに) 挿入するにはどうすればよいですか?

わかりました-この問題を解決でき、次のコードを実装できました:

     my $max_rows = 38;
my $rowcache = [];
my $sum   = 0;

if($fldnames eq "ALL"){ $fldnames = join(',', @{ $sth1->{NAME} });}

my $ins = $dbh2->prepare("insert into $database2.dbo.$tblname2 ($fldnames) values $fldvalues");

my $fetch_tuple_sub = sub { shift(@$rowcache) || shift(@{$rowcache=$sth1->fetchall_arrayref(undef, $max_rows)}) };

my @tuple_status;
my $rc;

$rc = $ins->execute_for_fetch($fetch_tuple_sub, \@tuple_status);

my @errors = grep { ref $_ } @tuple_status;

転送は機能しますが、SQL Server エクスポート/インポート ウィザードを使用して手動でデータを転送する場合よりもまだ遅くなります。私が気づいた問題は、データが行ごとに宛先に流れることであり、バルク転送サイズを増やすことができるかどうか疑問に思っていました. データのダウンロードは非常に高速ですが、ダウンロードとアップロードを組み合わせると速度が劇的に低下し、サーバー間で 5000 行のテーブルを転送するのに最大 10 分かかります。

4

2 に答える 2

2

ループの回避について具体的な質問をするよりも、目標 (速度?) を述べた方がよいでしょう。

Perl/DBI の場合:

DBI のexecute_arrayexecute_for_fetchを見てください。しかし、あなたがどの DBD を使用しているかを私たちに伝えていないので、それ以上は言えません。すべての DBD がバルク挿入をサポートしているわけではなく、DBI がそれをエミュレートしていない場合。DBD::Oracle と DBD::ODBC はそうします (最近のバージョンではodbc_array_operationsを参照)、後者ではデフォルトでオフになっています。

于 2012-08-09T08:40:06.523 に答える
1

使用している SQL Server のバージョンについては言及していません。まず、そのバージョンの「BULK INSERT」サポートを調べます。

また、関連する行数についても言及していません。それらがメモリに収まると仮定します。そうでない場合、一括挿入は機能しません。

そこから、の出力をfetchall_arrayref「BULK INSERT」操作に必要な構文に変換するのはあなた次第です。

于 2012-08-09T00:40:57.790 に答える