我试图在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提示符下不执行insert语句 - 它将转到命令shell。这是我得到的错误:
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `insert into tmp_tx_id values('664436565');'
有没有办法可以执行多个Insert语句,而不必每次都打开/关闭连接? 任何其他建议(甚至在Perl之外)都非常受欢迎 - 我是一名学习的程序员。
由于
答案 0 :(得分: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行插入的内容。
您还应该考虑installing modules on your system is not as impossible as it seems,然后将DBI
与占位符一起使用,就像其他每个使用数据库的Perl程序员一样。
答案 1 :(得分:0)
您可以使用sql插件准备一个脚本(可能不是整个文件,您可以将其拆分为100K插入块)并直接从命令行使用sqlplus执行它们,如下所示:
sqlplus <user@connect> @inserts.sql
在脚本文件的开头,您可以指定日志文件
spool '<logfile>'
加上你想要的任何选项(set trimspool on
对于调整行尾的空格非常有用)
最后:
commit ;
spool off
在perl中准备脚本很容易。