1

我正在尝试在 Linux 环境中将大量记录从 CSV 文件插入到 Oracle DB 中的表中。插入很简单 - CSV 具有需要插入到单个列表中的 ID,以进行进一步处理。

以下是我的思路: 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`;
}

这是错误的,因为您每次插入记录时都需要打开/关闭连接。我需要插入大量记录(> 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");

显然,插入语句不会在 SQL Plus 提示符下执行 - 它会转到命令 shell。这是我得到的错误:

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

有什么方法可以执行多个插入语句,而不必每次都打开/关闭连接?任何其他建议(甚至在 Perl 之外)都非常受欢迎 - 我是一名正在学习的程序员。

谢谢

4

2 回答 2

1

您可以将 shell 的 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 行插入的内容。

您还应该考虑在您的系统上安装模块并不像看起来那么不可能,然后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 回答