我需要将数据库中的表导出到制表符分隔值文件。我在 Perl 和 SQL Plus 上使用 DBI。它是否支持(DBI 或 SQL Plus)从 TSV 文件导出和导入?
我可以编写代码来满足我的需要,但是如果可用,我想使用现成的解决方案。
将表转储到具有制表符分隔值的文件应该相对简单。
例如:
open(my $outputFile, '>', 'myTable.tsv');
my $sth = $dbh->prepare('SELECT * FROM myTable');
$sth->execute;
while (my $row = $sth->fetchrow_arrayref) {
print $outputFile join("\t", @$row) . "\n";
}
close $outputFile;
$sth->finish;
请注意,如果您的数据包含制表符或换行符,这将无法正常工作。
根据您提供的信息,我猜您正在使用 DBI 连接到 Oracle 实例(因为您提到了 sqlplus)。
如果您想要一个“现成的”解决方案,如您所指出的,您最好的选择是使用“ yasql
”(Yet Another SQLplus)一个基于 DBD::Oracle 的数据库 shell 用于 oracle。
yasql 有一个简洁的功能,您可以编写一个 sql 选择语句并将输出直接从其安装的 shell(您需要 Text::CSV_XS)重定向到一个 CSV 文件。
另一方面,您可以使用DBD::Oracle和Text::CSV_XS滚动您自己的脚本。准备好并执行语句句柄后,您需要做的就是:
$csv->print ($fh, $_) for @{$sth->fetchrow_array};
假设您已使用选项卡作为记录分隔符初始化 $csv。有关详细信息,请参阅Text::CSV_XS文档
这是仅使用 awk 和 sqlplus 的方法。您可以使用存储 awk 脚本或复制/粘贴 oneliner。它使用 HTML 输出模式,因此不会破坏字段。
将此脚本存储为 sqlplus2tsv.awk:
# This requires you to use the -M "HTML ON" option for sqlplus, eg:
# sqlplus -S -M "HTML ON" user@sid @script | awk -f sqlplus2tsv.awk
#
# You can also use the "set markup html on" command in your sql script
#
# Outputs tab delimited records, one per line, without column names.
# Fields are URI encoded.
#
# You can also use the oneliner
# awk '/^<tr/{l=f=""}/^<\/tr>/&&l{print l}/^<\/td>/{a=0}a{l=l$0}/^<td/{l=l f;f="\t";a=1}'
# if you don't want to store a script file
# Start of a record
/^<tr/ {
l=f=""
}
# End of a record
/^<\/tr>/ && l {
print l
}
# End of a field
/^<\/td>/ {
a=0
}
# Field value
# Not sure how multiline content is output
a {
l=l $0
}
# Start of a field
/^<td/ {
l=l f
f="\t"
a=1
}
没有用长字符串和奇怪的字符对此进行测试,它适用于我的用例。有进取心的灵魂可以将此技术应用于 perl 包装器:)
过去我不得不这样做...我有一个 perl 脚本,您可以通过它传递您希望运行的查询并通过 sqlplus 将其传递给管道。这是一段摘录:
open(UNLOAD, "> $file"); # Open the unload file.
$query =~ s/;$//; # Remove any trailng semicolons.
# Build the sql statement.
$cmd = "echo \"SET HEAD OFF
SET FEED OFF
SET COLSEP \|
SET LINES 32767
SET PAGES 0
$query;
exit;
\" |sqlplus -s $DB_U/$DB_P";
@array = `$cmd`; # Execute the sql and store
# the returned data in "array".
print $cmd . "\n";
clean(@array); # Remove any non-necessary whitespace.
# This is a method to remove random non needed characters
# from the array
foreach $x (@array) # Print each line of the
{ # array to the unload file.
print UNLOAD "$x\|\n";
}
close UNLOAD; # Close the unload file.
当然,在上面我将它设为管道分隔符......如果你想要标签,你只需要 \t 而不是 | 在印刷品中。