我正试图在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");
显然,insert语句不是在SQLPlus提示符下执行的,而是进入命令shell。这是我得到的错误:
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `insert into tmp_tx_id values('664436565');'
有没有什么方法可以执行多个Insert语句,而不必每次都打开/关闭连接?任何其他建议(甚至是Perl之外的建议)都非常受欢迎——我是一个正在学习的程序员。
感谢
您可以将shell的heredoc表示法硬塞进Perl backticks表达式中,但可以考虑将sql命令写入文件的替代方案:
open my $fh, '>', '/tmp/my-inserts.sql';
print $fh "set heading offn", "set echo offn", ... ;
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线上插入内容的记录。
您还应该考虑到,在系统上安装模块并不像看上去那么不可能,然后像其他使用数据库的Perl程序员一样,使用带有占位符的DBI
。
您可以准备一个带有sql插入的脚本(可能不是整个文件,您可以将其拆分为100K插入的块),并使用sqlplus直接从命令行执行它们,如下所示:
sqlplus <user@connect> @inserts.sql
在脚本文件的开头,您可以指定一个日志文件
spool '<logfile>'
加上所需的任何选项(set trimspool on
可用于修剪行末尾的空格)最后:
commit ;
spool off
在perl中准备脚本将很容易。