Как я могу экспортировать таблицу Oracle в значения, разделенные табуляцией? - PullRequest
3 голосов
/ 06 января 2010

Мне нужно экспортировать таблицу в базе данных в файл значений, разделенных табуляцией. Я использую DBI на Perl и SQL Plus. Поддерживает ли он (DBI или SQL Plus) экспорт и импорт в или из файлов TSV?

Я могу написать код для своих нужд, но я бы хотел использовать готовое решение, если оно доступно.

Ответы [ 4 ]

2 голосов
/ 06 января 2010

Должен быть относительно простой вывод таблицы в файл со значениями, разделенными табуляцией.

Например:

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 голос
/ 03 января 2013

Вот подход только с 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:)

1 голос
/ 06 января 2010

Из предоставленной вами информации я предполагаю, что вы используете DBI для подключения к экземпляру Oracle (поскольку вы упомянули sqlplus).

Если вы хотите «готовое» решение, как вы указали, лучше всего использовать «yasql» (еще один SQLplus) для базы данных на базе DBD :: Oracle для Oracle.

В yasql есть замечательная функция, позволяющая написать оператор выбора sql и перенаправить вывод в файл CSV непосредственно из его оболочки (вам нужен Text :: CSV_XS), установленной для этого.

С другой стороны, вы можете свернуть свой собственный скрипт с помощью DBD :: Oracle и Text :: CSV_XS . После того, как ваши дескрипторы операторов подготовлены и выполнены, все, что вам нужно сделать, это:

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

Предполагается, что вы инициализировали $ csv с табуляцией в качестве разделителя записей. Подробнее см. Text :: CSV_XS Документация

0 голосов
/ 06 января 2010

В прошлом мне приходилось делать это ... У меня есть 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 вместо | в печати.

...