如何将Oracle表导出为制表符分隔值?

时间:2010-01-06 09:10:23

标签: perl dbi sqlplus

我需要将数据库中的表导出到制表符分隔值文件中。我在Perl和SQL Plus上使用DBI。它是否支持(DBI或SQL Plus)导出和导入TSV文件?

我可以编写一个代码来满足我的需求,但我想使用现成的解决方案(如果有的话)。

4 个答案:

答案 0 :(得分:2)

将表转储到具有制表符分隔值的文件应该相对简单。

例如:

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;

请注意,如果您的数据包含制表符或换行符,则无法正常工作。

答案 1 :(得分:1)

根据您提供的信息,我猜您正在使用DBI连接到Oracle实例(因为您提到了sqlplus)。

如果你想要一个“现成的”解决方案,你最好的选择是为oracle使用“yasql”(又一个SQLplus)基于DBD :: Oracle的数据库shell。

yasql有一个简洁的功能,你可以编写一个sql select语句,并直接从它的shell(你需要Text :: CSV_XS)将输出重定向到CSV文件。

另一方面,您可以使用DBD::OracleText::CSV_XS滚动自己的脚本。准备好并执行语句句柄后,您需要做的就是:

$csv->print ($fh, $_) for @{$sth->fetchrow_array};

假设您已使用tab作为记录分隔符初始化$ csv。有关详细信息,请参阅Text::CSV_XS文档

答案 2 :(得分:1)

这是一种仅使用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包装:)

答案 3 :(得分:0)

我过去必须这样做...我有一个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而不是|在印刷品中。