tags:

views:

351

answers:

3

I need to export a table in the database to a tab separated values file. I am using DBI on Perl and SQL*Plus. Does it support (DBI or SQL*Plus) 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.

+1  A: 

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.

mopoke
It is usually best to avoid a raw join to produced a structured file lest any data column contains an embedded tab. To avoid issues it would be best to use Text::CSV_XS so that the separator inside a column is embedded by double quotes. You have correctly warned against this situation. Using Text::CSV_XS would be more robust
Gurunandan
If any of the data have tabs (maybe just from binary data), this will get you in trouble. You can use Test::CSV_XS to construct the records.
brian d foy
+1  A: 

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

Gurunandan
A: 

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.

Courtland