1

Linux 環境で、CSV ファイルから Oracle DB のテーブルに多数のレコードを挿入しようとしています。挿入は簡単です。CSV には、さらに処理するために単一の列テーブルに挿入する必要がある ID があります。

1. ファイルを配列に読み込む 2. 配列内の各項目をループしてテーブルに挿入する

SQL *Loader または DBI を使用できません。DB サーバーへのアクセスが制限されており、DB への接続に使用するホストに追加のパッケージをインストールすることはできません。そのため、利用可能な最も単純なものを使用する必要があります。

これが機能する作品です:

#!/usr/bin/perl
use warnings;
use strict;

my $returnVar;
my $inputfile = $ARGV[0];

# Read file into an array
open(FILE, "<", $inputfile) or die("Unable to open file: $inputfile");
my @idlist = <FILE>;
close(FILE);

#insert array into table
foreach my $id(@idlist)
{
   chomp($id);
   $returnVar = `sqlplus -s cvo/cvo123\@CVOSTAGE\ <<END
        set heading off
                    set echo off
                    set feedback off
                    set pagesize 0
        insert into tmp_tx_id values('$id');
        exit`;
}

これは、レコードを挿入するたびに接続を開いたり閉じたりする必要があるという意味で問題があります。多数のレコード (> 100 万) を挿入する必要がありますが、これは恐ろしい方法です。次の方法で変更しようとしましたが、成功しません。

.
.
<File has been read into the array>

$returnVar1 = `sqlplus -s cvo/cvo123\@CVOSTAGE\ <<END
                      set heading off
                      set echo off
                      set feedback off
                      set pagesize 0`;

foreach my $id(@idlist)
{
    chomp($id);
    $returnVar2 = `insert into tmp_tx_id values(\'$id\');`;
}
system("exit");

どうやら、insert ステートメントは SQL Plus プロンプトでは実行されず、コマンド シェルに移動します。これは私が得るエラーです:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `insert into tmp_tx_id values('664436565');'

毎回接続を開いたり閉じたりすることなく、複数の Insert ステートメントを実行する方法はありますか? 他の提案 (Perl 以外でも) は大歓迎です。私は学習中のプログラマーです。

ありがとう

4

2 に答える 2

1

シェルのヒアドキュメント表記を Perl のバッククォート式に押し込むこともできますが、SQL コマンドをファイルに書き込む別の方法を検討してください。

open my $fh, '>', '/tmp/my-inserts.sql';
print $fh "set heading off\n", "set echo off\n", ... ;
foreach my $id(@idlist)
{
    chomp($id);
    print $fh "insert into tmp_tx_id values('$id');";
}
close $fh;

... and then ...

$returnVar1 = `sqlplus -s cvo/cvo123\@CVOSTAGE  < /tmp/my-inserts.sql`;

これにより、デバッグが容易sqlplusになるという利点があります。4683 行目にエラーがあったことが通知されると、4683 行に何を挿入しようとしたかが記録されます。

また、システムにモジュールをインストールすることは見かけほど不可能ではないことを考慮しDBI、データベースを操作する他のすべての Perl プログラマーと同様にプレースホルダーと共に使用する必要があります。

于 2013-07-25T19:04:11.380 に答える
0

SQL 挿入を使用してスクリプトを準備し (ファイル全体ではない可能性があります。100K 挿入のチャンクに分割できます)、sqlplus を使用してコマンド ラインから直接実行できます。

sqlplus <user@connect> @inserts.sql

スクリプト ファイルの先頭で、ログ ファイルを指定できます。

spool '<logfile>'

さらに、必要なオプション(set trimspool on行末のスペースをトリミングするのに役立ちます)と最後に:

commit ;
spool off

perl でスクリプトを準備するのは簡単です。

于 2013-07-25T20:39:51.553 に答える