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

发布于 2024-08-16 13:07:37 字数 132 浏览 9 评论 0原文

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

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

I need to export a table in the database to a tab separated values file. I am using DBI on Perl and SQLPlus. Does it support (DBI or SQLPlus) exporting and importing to or from TSV files?

I can write a code to do my need, But I would like to use a ready made solution if it is available.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忆沫 2024-08-23 13:07:37

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

例如:

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;

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

It should be relatively simple to dump a table to a file with tab-separated values.

For example:

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;

Note that this will not work well if your data contains either a tab or a newline.

浅紫色的梦幻 2024-08-23 13:07:37

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

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

yasql 有一个巧妙的功能,您可以编写 sql select 语句并将输出直接从其 shell 重定向到 CSV 文件(您需要为此安装 Text::CSV_XS)。

另一方面,您可以使用 DBD::Oracle 和 < a href="http://search.cpan.org/perldoc?Text::CSV_XS" rel="nofollow noreferrer">Text::CSV_XS。准备并执行语句句柄后,您需要做的就是:

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

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

From the information you have provided I am guessing you are using DBI to connect to an Oracle instance (since you mentioned sqlplus).

If you want a "ready made" solution as you have indicated, your best bet is to use "yasql" (Yet Another SQLplus) a DBD::Oracle based database shell for oracle.

yasql has a neat feature that you can write an sql select statement and redirect the output to a CSV file directly from its shell (You need Text::CSV_XS) installed for that.

On the other hand you can roll your own script with DBD::Oracle and Text::CSV_XS. Once your statement handles are prepared and executed, all you need to do is:

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

Assuming you have initialised $csv with tab as record separator. See the Text::CSV_XS Documentation for details

紫﹏色ふ单纯 2024-08-23 13:07:37

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

Here's an approach with awk and sqlplus only. You can use store the awk script or copy/paste the oneliner. It uses the HTML output mode so that fields are not clobbered.

Store this script as 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
}

Didn't test this with long strings and weird characters, it worked for my use case. An enterprising soul could adapt this technique to a perl wrapper :)

只有一腔孤勇 2024-08-23 13:07:37

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

I have had to do that in the past... I have a perl script that you pass the query you wish to run and pipe that through sqlplus. Here is an excerpt:

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.

Of course above I am making it pipe delimeted... if you want tabs you just need the \t instead of the | in the print.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文