2013-07-25 1 views
1

Я пытаюсь вставить большое количество записей из файла CSV в таблицу в Oracle DB в среде Linux. Вставка проста - CSV имеет идентификаторы, которые необходимо вставить в одну таблицу столбцов для дальнейшей обработки.Perl: несколько вставок Таблица Oracle DB из CSV

Потом была моя линия мысли: 1. Прочитайте файл в массив 2. Петля по каждому элементу массива и вставить его в таблицу

Я не могу использовать SQL * Loader или DBI, в доступ к серверу БД ограничен, и мне не разрешено устанавливать какие-либо дополнительные пакеты на хост, которые я использую для подключения к БД. Поэтому мне нужно использовать самые простые вещи.

Вот кусок, который работает:

#!/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`; 
} 

Это неисправно в том смысле, что вам нужно, чтобы открыть/закрыть соединение каждый раз при вставке записей. Мне нужно вставить большое количество записей (> 1 миллион), и это, я согласен, это ужасный способ сделать это. Я попытался изменить его следующим образом, но я не увенчались успехом:

. 
. 
<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"); 

Очевидно, что оператор вставки не выполняется на SQL Plus приглашение - он идет к командной оболочке. Это ошибка, я получаю:

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

Есть ли способ, что я могу выполнить несколько операторов Insert, без необходимости открывать/закрывать соединение каждый раз? Любые другие предложения (даже за пределами Perl) действительно приветствуются - я программист в обучении.

Благодаря

ответ

1

Вы могли впихнуть Heredoc обозначения командного интерпретатора в выражение 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.

Вы также должны принять во внимание, что installing modules on your system is not as impossible as it seems, а затем использовать DBI с заполнителями, как и любой другой программист Perl, который работает с базами данных.

0

Вы можете подготовить сценарий с SQL вставками (возможно, не весь файл, вы можете разбить его на куски 100K вставок) и выполнить их непосредственно из командной строки с SQLPLUS, как это:

sqlplus <[email protected]> @inserts.sql 

в начале файла сценария можно указать файл журнала

spool '<logfile>' 

плюс любые варианты, которые вы хотите (set trimspool on полезно для Triming пространства в конце линии) и в конце:

commit ; 
spool off 

Будет легко подготовить сценарий (ы) в perl.

Смежные вопросы