Re: How to unload Oracle in ASCII flat files?
Date: Tue, 15 Feb 1994 13:16:28 GMT
Message-ID: <CL9ovH.5o8_at_ireq.hydro.qc.ca>
Vladimir Rubashevsky (rubashev_at_hpcc01.corp.hp.com) wrote:
: Hi everybody.
: I am new to this group so excuse me if you already discussed this issue.
: Our project needs to Unload a good amount of data from Oracle database.
: The data should be in a classic flat file format with fixed length ASCII
: records.
: Do you know any good tool(s) to do it. I tried select * with various options,
: but it is very slow. And apparently Oracle does not provide tools for it.
: Their Export/Import facility creates a flat file in a very special format
: which cannot be readable by a non-Oracle application.
: Thanks.
: Vladimir.
One interesting solution is the unloadr script written by Jeff Stander (Jeff.Stander_at_ml.csiro.au). It's an oraperl script that will extract Oracle information into flat files (table structure description, flat file data dump, SQL*Loader format, sql format) and has many functional parameters.
Here it is...
----Cut here---------------------------------------#!/usr/local/bin/oraperl
'di';
'ig00';
############################################################################### # _at_(#) unloadr : dump data from Oracle table to ASCII "merge" file # _at_(#) SunOS deep sun4c (jstander) # _at_(#) loc: /home/jstander/bin # _at_(#) $Revision 1.0 $ (jstander 07.06.93): new # # Name # unloadr
#
$Synopsis=<<X;
unloadr [-dmlsHhnpbqSO] [-Fc] [-D{dfmt}] [-f{fetchlimit}] [-w{where..}] [-o{outfile}] <table_name|_at_file>..X
# Description # dumps Oracle table as ASCII flat file in "merge" format, which has # each field comma-delimited and enclosed by quotes. # $Options=<<X; -d create .dex file - table structure description -m create .mrg file - flat file data dump -l create .ctl file - for Oracle SQLLOAD -s create .sql file - re-create table in Oracle -n suppress printing of quote marks around each field -h help -H First line of the output file holds field names, comma-separated -p send output to \$PRINTCMD, your favorite spooler ("/home/jstander/bin/printw" if not defined) -b browse mode, send output to $PAGER (default="more") -q Quiet mode. Don't report actions to STDERR. -S Dump SQL statement used for merge extraction. -O output is redirected to stdout -Fc change field separator character to c. -x pipe output to xtmsg -o{outfile} output is redirected to outfile if present -D{dfmt} set date format (default='DD-MON-YYYY HH:24MI') -f{fetchlimit} fetch only <fetchlimit> records from the database -Cz compress output with 'zip' -Cc compress output with 'compress' Default is to direct output to <tablename>.mrg No unloading is done. -w{whereclause} A SQL expression to restrict SELECTed records from table. Note only the expression should be passed, not "WHERE =", see example below. tablename Name of the table to be unloaded. The column defini- tions are extracted and a generic SQL statement is automatically constructed to SELECT all columns for unloading, subject only to the restrictions of the -w option. The user may supply their own SQL statement to select columns for unloading by writing the SQL statement into a file and giving the file name, preceeded by an '_at_' character, in place of the "tablename" argument.X
# Note # Any field name ending in "COMMENT(S)" is right-trimmed before unloading. # Any embedded newlines in the COMMENT(S) field are converted to the # meta-char "\n" # # Example # Unload all data for cruise number RTMP92-02 from a table called # RTMP_OBS_VES_ENTRY. Output will be to the file RTMP9202.ves. # # unloadr -w "cruise_num='RTMP92-02'" -o RTMP9202.ves rtmp_obs_ves_entry # # Bugs # Need to change login to handle OPS$db.table or db.table for table name # Clusters need to be handled correctly when creating table create .sql file # Clustering ignored for now. # Constraints not extracted when creating dex or sql files. # Author # Jeff.Stander_at_ml.csiro.au # CSIRO Division Of Fisheries # Hobart, Tasmania 7001, Australia ###############################################################################
require "getopts.pl";
require "pwd.pl";
require 'ctime.pl';
sub today {
#------------------------------------------------------------------------------ # today returns the date in one of six formats, depending on the argument # 1 25 Jul 93 - dd mmm yy # 2 25 Jul 1993 - dd mmm yyyy # 3 25/06/93 - European/Australian format # 4 06/25/93 - U.S.A. format # 5 13:08 - hh:mm # 6 13:08:24 - hh:mm:ss #------------------------------------------------------------------------------ local($format) = _at__ ? @_ : 1; local($sec, $min, $hour, $mday, $mon, $year, $wday, $YEAR, $tod, $month, $res); ($wday, $month, $mday, $tod, $YEAR) = split(' ',&ctime(time)); ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime(time); if ( $format == 1 ) { $res=sprintf("%02d %s %02d",$mday,$month,$year) } if ( $format == 2 ) { $res=sprintf("%02d %s %02d",$mday,$month,$YEAR) } if ( $format == 3 ) { $res=sprintf("%02d/%02d/%02d",$mday,$mon,$year) } if ( $format == 4 ) { $res=sprintf("%02d/%02d/%02d",$mon,$mday,$year) } if ( $format == 5 ) { $res=sprintf("%02d:%02d",$hour,$min) } if ( $format == 6 ) { $res=$tod } $res;
}
#----------------------------------------------------------------------------- # Print line withoffset, split at word boundary # Synopsis: printdex(offset,length,dex) # Arguments: # offset - offset from left margin in character spaces # length - total length of line including offset in character spaces # dex - line to print #------------------------------------------------------------------------------ sub printdex { local($offset,$width,$dex) = _at__; $width = 80 if !$width; $offset = 0 if !$offset; local(_at_words) = split (/\s/,$dex); local($out,$leader,$result); $leader = sprintf("%${offset}s",""); foreach $word (_at_words) { if (length($out) + length($word) > $width-$offset) { $result .= $leader . $out . "\n"; $out = ""; } $out .= "$word "; } $result .= $leader . $out . "\n" if $out; $result;
}
#-----------------------------------------------------------------------------# Extract first line of output from oracle given SQL query
#------------------------------------------------------------------------------ sub sqlx { local($sqlstmt,$passwd,$db) = _at__; local($sqlx_lda,$nologon); ($user=$passwd)=~s/\/.*$//; $passwd=~s/^.*\///; $nologon = sprintf("%s",$user) =~ /^0x/ || 0; if ( $nologon ) { $sqlx_lda=$user; } else { $sqlx_lda = &ora_login($db,$user,$passwd) || die $ora_errstr; } $csr = &ora_open($sqlx_lda,$sqlstmt) || die $ora_errstr; _at_result = &ora_fetch($csr); &ora_close($csr); &ora_logoff($sqlx_lda) if !$nologon; _at_result;
}
$TABLE=FOP; sub openf {
#------------------------------------------------------------------------------ # Subroutine to open a file in "r" or "w" mode and return error # message and status if unable to open file.# Synopsis: openf(<r|w|filter>,filehandle,name);
#------------------------------------------------------------------------------
local($type,$handle,$name,$filter) = _at__; if ($type eq "w") {
open($handle,"> $name"); stat($name); print STDERR "$NAME: file not writeable: $name\n" if !-w_; -w_;
}
elsif ($type eq "r") {
stat($name); print STDERR "$NAME: file not found: $name\n" if !-e_; -e_ && print STDERR "$NAME: file not readable: $name\n" if !-r_; -r_ && open($handle,"< $name"); -r_;
}
elsif ($type eq "p") {
open($handle,"| $filter $name");
}
else {
die "$NAME: sub openf arg 1 must be r, w, or p.'\n"; 1;
}
}
($NAME=$0) =~ s/^.*\///;
$Pager=$ENV{'PAGER'};
if ( length($Pager) == 0 ) { $Pager="more"; }
$Printcmd=$ENV{'PRINTCMD'};
if ( length($Printcmd) == 0 ) { $Printcmd="/home/jstander/bin/printlp"; }
#------------------------------------------------------------------------------# Process command line arguments
#------------------------------------------------------------------------------&Getopts('LUuzdmlshHnpbqxSOF:D:f:o:w:C:') || exit ;
if ( $opt_z || $#ARGV < 0 ) { # if no arguments, send usage $Synopsis =~ s/^[ \t]*//; print STDERR "Usage:\t$Synopsis"; print STDERR $Options if $opt_h; exit;
}
open(UNAME,"uname -snm |");
$uname = <UNAME>;
chop($uname);
close(UNAME);
$HOME = $ENV{'HOME'} ? $ENV{'HOME'} : (getpwuid($<))[7]; $USERNAME = $ENV{'USERNAME'} ? $ENV{'USERNAME'} : (getpwuid($<))[6]; $USER = $ENV{'USER'} ? $ENV{'USER'} : (getpwuid($<))[1];
$USERNAME_p="($USERNAME)";
if ( $opt_b ) { $ENV{'COLUMNS'}="132"; $out="| $Pager"; }
$header = $opt_H; $xbox = $opt_x; $printout = $opt_p; $redirect = $opt_O; $dumpsql = $opt_S; $dfmt = $opt_D || "DD-MON-YYYY HH24:MI"; $fetchlimit = $opt_f; $where = $opt_w; $quiet = $opt_q; $opt_u = 1 if $opt_U; $opt_u = 1 if $opt_L; $sep = $opt_F ? $opt_F : ","; $quote = $opt_n ? "" : "\"";
if ( $opt_u ) {
$opt_d = 1; $redirect = 1; $quiet = 1;
}
if ( !$opt_d && !$opt_m && !$opt_l && !$opt_s ) {
$opt_d=1; $opt_m=1; $opt_l=1; $opt_s=1;
}
#------------------------------------------------------------------------------# Loop over command arguments: they are either tables or SQL statement files
#------------------------------------------------------------------------------while (!($#ARGV<0)) {
($table=$ARGV[0]) =~ tr/A-Z/a-z/;
$table =~ s/^.*\.//; # this strips the tablespace name off, should be changed($TABLE=$table) =~ tr/a-z/A-Z/;
shift;
if ( ($readsql=$table =~ s/^_at_//) ) {
$file=$table; &openf("r",FILEIN,$file) || exit;
}
if ( $redirect ) {
$out=""; $outname=""; $opt_o=0;
}
else {
$outname=$opt_o || $table;
}
$lda = &ora_login("","intg","gtni") || die $ora_errstr;
if ( !$dumpsql && !$quiet && !$readsql ) {
print STDERR "\n$NAME: extracting data from table: $table\n"; }
if ( $readsql ) {
#--------------------------------------------------------------------------- # This processes a user-provide SQL statement and extracts column names found # between the SELECT .. FROM keywords. # The SQL statement is preserved intact in the array _at_qh. # Note: This assumes the user provides a fairly vanilla SQL statement for # an unload operation, i.e. no column aliases and subquerys, but data# conversion (e.g. to_char(), decode(), etc., are ok.)
#--------------------------------------------------------------------------- $qh=""; while (<FILEIN>) { # strip out comments $_ =~ s/;$//; $qh .= $_; $_ =~ tr/a-z/A-Z/; $_ =~ s/^[ \t]*//; $_ =~ s/[ \t]*$//; $_ =~ s/--.*$//; if ( $ok && $_ =~ /^FROM[ \t]*/ ) { $ok=0; $from++; s/FROM[ \t]*// } if ( $_ =~ s/^SELECT// ) { $ok=1; } if ( $from == 1 ) { $from++; if ( $_ =~ /^[a-zA-Z]/ ) { $_ =~ s/[ \t\n]//g; $TABLE = $_; $_ =~ tr/A-Z/a-z/; $table = $_ ; $outname = $table if !$outname; $from=0; next; } } $ok || next; # This mess extracts the column name, The "^" char. is a placeholder. $_ =~ s/\^//g; $_ =~ s/[ \t]*[^(,]*\(/^/g; $_ =~ s/,[^^]*\)//g; $_ =~ s/\),/,/g; $_ =~ s/\^//g; $_ =~ s/[ \t\n]//g; _at__ = split(/,/,$_); for ( $i=0; $i<=$#_; $i++ ) { $column[$ncols++] = _at__[$i]; } } if ( $opt_l ) { $in_expr="AND column_name IN ("; for ( $i=0; $i<=$#column; $i++ ) { $col = _at_column[$i]; $in_expr .= "\n\t\t'$col',"; } } $in_expr =~ s/.$/\n\t)/; print STDERR "\n$NAME: extracting data from table: $table\n" if !$quiet && !$dumpsql;
}
else {
#------------------------------------------------------------------------------# Extract column names from the table
#------------------------------------------------------------------------------ $qh=<<EOI; SELECT column_name, data_type FROM user_tab_columns WHERE table_name='$TABLE' ORDER BY column_id
EOI $csr = &ora_open($lda,$qh) || die $ora_errstr;
$ncols=0; while (($column[$ncols],$datatype[$ncols]) = &ora_fetch($csr)) { $ncols++; } if ( !$ncols ) { !$quiet && print STDERR "$NAME: Table not found: $table\n" ; exit; } &ora_close($csr); #------------------------------------------------------------------------------ # Using column names for given table, assemble the SQL statement to extract# the columns
#------------------------------------------------------------------------------ $qh="SELECT"; for ( $i=0; $i<$ncols; $i++ ) { $fld = $column[$i]; $dt = $datatype[$i]; $qh .= "\t"; if ($fld =~ 'COMMENT[S]*') { $qh .= "rtrim($fld)"; } elsif (!($dt =~ 'DATE')) { $qh .= $fld } else { $qh .= "to_char( $fld,"; if (length($dfmt) > 0) { $qh .= "$item '$dfmt'" } $qh .= $item . " )"; } if ( $i<$ncols-1 ) { $qh .= ",\n"; } } $qh .= "\nFROM\t$TABLE"; if ( $where ) { $qh .= "\nWHERE $where"; }}
#------------------------------------------------------------------------------# if -S option, print SQL stmt and exit
#------------------------------------------------------------------------------ if ( $dumpsql ) { print STDOUT "$qh\n"; exit;
}
if ( !$dumpsql ) {
if ( $opt_C ) { if ( $opt_C eq "z" ) { if ( $quiet ) { $v = "-qq"; } else { print STDERR "$NAME: output will be compressed using zip." . " Restore with -p pipe option.\n"; } $filter = "zip $v $outname.zip -"; } else { if ( !$quiet ) { $v = "-v"; print STDERR "$NAME: output will be " . "compressed using compress\n"; } $filter = "compress $v"; } if ( !$quiet ) { } }
}
#------------------------------------------------------------------------------# get storage data for this table
#------------------------------------------------------------------------------ if ( $opt_d || $opt_s ) { ($tablespace_name,$cluster_name,$initial_extent,$next_extent,$pct_increase) = &sqlx(<<EOI,"",""); SELECT tablespace_name, cluster_name, initial_extent, next_extent, pct_increase FROM user_tables WHERE table_name='$TABLE'
EOI
}
#------------------------------------------------------------------------------# Get file handle names
#------------------------------------------------------------------------------ if ( $redirect ) { $out_mrg = ""; $out_dex = ""; $out_ctl = ""; $out_sql = ""; open(OUT_MRG,"| cat") if $opt_m ; open(OUT_DEX,"| cat") if $opt_d ; open(OUT_SQL,"| cat") if $opt_s ; open(OUT_CTL,"| cat") if $opt_l ;
}
elsif ( $outname ) {
$out_mrg = "$outname.mrg"; $out_dex = "$outname.dex"; $out_ctl = "$outname.ctl"; $out_sql = "$outname.sql"; $outtype=".";
}
if ( $xbox ) {
$out_mrg="| xbox -h TABLENAME: $TABLE"; $out_dex="| xbox -h TABLENAME: $TABLE"; $out_ctl="| xbox -h TABLENAME: $TABLE"; $out_sql="| xbox -h TABLENAME: $TABLE"; open(OUT_MRG,$out_mrg) if $opt_m ; open(OUT_DEX,$out_dex) if $opt_d ; open(OUT_SQL,$out_sql) if $opt_s ; open(OUT_CTL,$out_ctl) if $opt_l ; $outtype="to xbox"; $quiet=1;
}
elsif ( $printout ) {
$out_mrg="| $Printcmd -q -s -a -h $table.mrg"; $out_dex="| $Printcmd -q -s -a -h $table.dex"; $out_ctl="| $Printcmd -q -s -a -h $table.ctl"; $out_sql="| $Printcmd -q -s -a -h $table.sql"; open(OUT_MRG,$out_mrg) if $opt_m ; open(OUT_DEX,$out_dex) if $opt_d ; open(OUT_SQL,$out_sql) if $opt_s ; open(OUT_CTL,$out_ctl) if $opt_l ; $outtype="to printer.";
}
elsif ( !$redirect ) {
&openf("w",OUT_MRG,$out_mrg) || exit if $opt_m ; &openf("w",OUT_DEX,$out_dex) || exit if $opt_d ; &openf("w",OUT_SQL,$out_sql) || exit if $opt_s ; &openf("w",OUT_CTL,$out_ctl) || exit if $opt_l ;}
#------------------------------------------------------------------------------ # Process query using SQL statement and retrieve each record # Record is processed field-by-field into single output string with each # field comma separated and delimited by double-quotes.# Fetchlimit (-f#) allows you to dump a few records to see how its going.
#------------------------------------------------------------------------------ if ( $opt_m ) { $csr = &ora_open($lda,$qh) || die $ora_errstr; $cnt=0; $maxline=0; if ( $header ) { for ( $i=0; $i<$ncols; $i++ ) { print OUT_MRG "$column[$i]"; if ( $i<$ncols-1 ) { print OUT_MRG "," } else { print OUT_MRG "\n"; } } } while ( !$done && (_at_SELECT = &ora_fetch($csr)) ) { if ( !$fetchlimit || $cnt < $fetchlimit ) { $out=$quote; for ( $i=0; $i<=$#SELECT; $i++ ) { $SELECT[$i] =~ s/[\n]/\\n/g; $SELECT[$i] =~ s/["]/'/g; $out .= "$SELECT[$i]$quote"; if ( $i < $#SELECT ) { $out .= $sep . $quote; } } print OUT_MRG "$out\n"; if ( $maxline < ($l=length($out)) ) { $maxline = $l } $cnt++; } else { $done=1 } } if ( !$quiet ) { print STDERR "$NAME: extracted $cnt records with $ncols fields each\n"; print STDERR "$NAME: maximum line length is $maxline\n"; } &ora_close($csr); close(OUT_MRG); $outname && !$quiet && print STDERR "$NAME: $outname.mrg written$outtype\n";}
#------------------------------------------------------------------------------# Create the *.ctl file to pass to oracle loader sqlload
#------------------------------------------------------------------------------if ( $opt_l ) {
#----------------------------------------------------------------------- # Get user name from database #----------------------------------------------------------------------- $qh=<<EOI; SELECT initcap(username) FROM user_users
EOI
$csr = &ora_open($lda,$qh) || die $ora_errstr; _at_username = &ora_fetch($csr); &ora_close($csr); #----------------------------------------------------------------------- # Get table comments from database #----------------------------------------------------------------------- $qh=<<EOI; SELECT initcap(table_name), comments FROM user_tab_comments WHERE table_name='$TABLE' AND table_type='TABLE'
EOI
$csr = &ora_open($lda,$qh) || die $ora_errstr; _at_tablecomment = &ora_fetch($csr); &ora_close($csr); $maxline=0; $cnt=0; $date=&today(1); #----------------------------------------------------------------------- # Print ctl file header #----------------------------------------------------------------------- print OUT_CTL <<EOI; ----------------------------------------------------------------------------- -- $table.ctl : use with $table.sql and $table.mrg -- $uname ($ENV{'USER'}) $USERNAME -- loc: $ENV{'PWD'}/$outname.ctl
-- \$Revision 1.0 $ ($USER) $date: new
LOAD DATA
INFILE "$table.mrg"
INSERT
INTO TABLE $TABLE
FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS
(
EOI
#----------------------------------------------------------------------- # Get column details from database #----------------------------------------------------------------------- $qh=<<EOI; SELECT initcap(column_name), initcap(data_type) FROM user_tab_columns WHERE table_name='$TABLE' $in_expr ORDER BY column_id
EOI $csr = &ora_open($lda,$qh) || die $ora_errstr;
$cnt=0; while (( $column_name, $data_type) = &ora_fetch($csr) ) { if ( $cnt++ > 0 ) { print OUT_CTL ",\n"; } if ( $data_type eq "DATE" ) { print OUT_CTL " $column_name DATE '$dfmt'"; } else { print OUT_CTL " $column_name"; } } &ora_close($csr); print OUT_CTL "\n)\n"; close(OUT_CTL); $outname && !$quiet && print STDERR "$NAME: $outname.ctl written$outtype\n";}
#------------------------------------------------------------------------------# Create the .sql file to (re)create the table
#------------------------------------------------------------------------------if ( $opt_s ) {
$outname=$table if !$outname;
print OUT_SQL <<EOI;
/***************************************************************************** * $outname.sql : use with $outname.ctl and $outname.mrg * By: $ENV{'USER'} $USERNAME_p * loc: $ENV{'PWD'}/$outname.sql
- \$Revision 1.0 $ ($ENV{'USER'} $date): new *****************************************************************************/ CREATE TABLE $table ( EOI
SELECT initcap(column_name), initcap(data_type), data_length , data_precision, data_scale, nullable FROM user_tab_columns WHERE table_name='$TABLE'
ORDER BY column_id
EOS
$csr = &ora_open($lda,$qh) || die $ora_errstr; while (( $column_name, $data_type, $data_length , $data_precision, $data_scale, $nullable) = &ora_fetch($csr) ) { $null=""; $dec=""; $prec=""; $null=" NOT NULL" if $nullable eq "N"; if ( $data_type eq "NUMBER" ) { $prec="($data_precision"; if ( $data_scale !~ /0/ ) { $prec .= ",$data_scale"; } $prec .= ")"; } elsif ( $data_type eq "DATE" ) { $prec=""; } else { $prec = "($data_length)"; } $outsql .= sprintf(" %s %s%s%s,\n", $column_name,$data_type,$prec,$null); } $Tablespace = " TABLESPACE $tablespace_name\n"; $Storage = " STORAGE INIT $initial_extent NEXT $next_extent PCTINCREASE $pct_increase\n"; $outsql =~ s/,$/\n$Tablespace$Storage);/; print OUT_SQL $outsql; &ora_close($csr); $qh=<<EOS; SELECT 'COMMENT ON TABLE ' || initcap(TABLE_NAME) || ' IS ''' || comments || ''';' FROM user_tab_comments WHERE table_name='$TABLE' AND table_type='TABLE';
EOS $qh=<<EOS;
SELECT 'COLUMN ' || table_name || '.' || initcap(column_name), comments FROM user_col_comments WHERE table_name='$TABLE' UNION SELECT 'TABLE ' || initcap(table_name), comments FROM user_tab_comments WHERE table_name='$TABLE'
EOS
$csr = &ora_open($lda,$qh) || die $ora_errstr; while ( ($colname,$comment) = &ora_fetch($csr) ) { print OUT_SQL "COMMENT ON $colname IS\n '$comment';\n" if $comment; } &ora_close($csr); close(OUT_SQL); $outname && !$quiet && print STDERR "$NAME: $outname.sql written$outtype\n";}
#------------------------------------------------------------------------------# Create summary table description
#------------------------------------------------------------------------------if ( $opt_u ) {
!opt_L && print OUT_DEX <<EOI;
Table_name: $table
Seq# Name Null? Type ---- ----------------------------------- -------- --------EOI
#----------------------------------------------------------------------- # Get column details #----------------------------------------------------------------------- $qh=<<EOI; SELECT initcap(col.column_name), initcap(data_type), data_length, data_precision, data_scale, nullable, comments FROM user_tab_columns col, user_col_comments com WHERE col.table_name='$TABLE' AND com.table_name='$TABLE' AND col.column_name=com.column_name ORDER BY column_id
EOI $csr = &ora_open($lda,$qh) || die $ora_errstr;
while (( $column_name, $data_type, $data_length , $data_precision, $data_scale, $nullable, $comments) = &ora_fetch($csr) ) { $nullable = ($nullable eq "Y") ? "" : "NOT NULL"; $dec=""; $dtype=$data_type; if ( $data_type eq "Number" ) { if ( $data_scale ne "0" ) { $dec = $data_scale; } $len = $data_precision; } elsif ( $data_type eq "Date" ) { $len=""; } else { $len = $data_length; } $dtype = $data_type . "(" . $len if $len; $dtype .= "," . $dec if $dec; $dtype .= ")" if $len; if ( $opt_L ) { printf OUT_DEX ("%s %s\n",$column_name,$dtype); } else { $column_name =~ tr/a-z/A-Z/; $dtype =~ tr/a-z/A-Z/; printf OUT_DEX ("%5d %-35s %8s %s\n", ++$cnt,$column_name,$nullable,$dtype); } print OUT_DEX &printdex( 6,60,$comments ) if $opt_U && length($comments); $len=0; $dec=0; } &ora_close($csr); close(OUT_DEX);
}
elsif ( $opt_d ) {
#------------------------------------------------------------------------------# Create the .dex file
#------------------------------------------------------------------------------ #----------------------------------------------------------------------- # Get user name from database #----------------------------------------------------------------------- $qh=<<EOI; SELECT initcap(username) FROM user_users
EOI
$csr = &ora_open($lda,$qh) || die $ora_errstr; _at_orauser = &ora_fetch($csr); &ora_close($csr); #----------------------------------------------------------------------- # Get table comments from database #----------------------------------------------------------------------- $qh=<<EOI; SELECT initcap(table_name), comments FROM user_tab_comments WHERE table_name='$TABLE' AND table_type='TABLE'
EOI
$csr = &ora_open($lda,$qh) || die $ora_errstr; _at_tablecomment = &ora_fetch($csr); &ora_close($csr); $maxline=0; $cnt=0; $date=&today(1) . " _at_ " . &today(5); #----------------------------------------------------------------------- # Print dex file header #----------------------------------------------------------------------- $Tablespace = "Tablespace: $tablespace_name\n" if $tablespace_name; $Cluster = "Cluster: $cluster_name\n" if $cluster_name; $Storage = "Storage: INIT $initial_extent" if $initial_extent; $Storage .= " NEXT $next_extent" if $next_extent; $Storage .= " PCTINCREASE $pct_increase" if $pct_increase; $Storage .= "\n" if $Storage; print OUT_DEX <<EOI; ----------------------------------------------------------------------------- Table name: $tablecomment[0]
Description: $tablecomment[1]
Oracle User ID: $orauser[0]
Database: Author: $USERNAME Revision: Unloaded: $date By user: $ENV{'USER'} Location: $ENV{'PWD'}/$outname.dex $Tablespace$Cluster${Storage}Note: Use 'mkloadf' to generate CREATE TABLE SQL script from this file(c) Copyright 1993, CSIRO Div. of Fisheries, Hobart Tasmania, Australia
Fld Field Type Len Dec Nul Comment No Name Ok ---- --------------------- -------- -------- --- --- ----------------------EOI
#----------------------------------------------------------------------- # Get column details and comments from database #----------------------------------------------------------------------- $qh=<<EOI; SELECT initcap(col.column_name), initcap(data_type), data_length, data_precision, data_scale, nullable, comments FROM user_tab_columns col, user_col_comments com WHERE col.table_name='$TABLE' AND com.table_name='$TABLE' AND col.column_name=com.column_name ORDER BY column_id
EOI $csr = &ora_open($lda,$qh) || die $ora_errstr;
while (( $column_name, $data_type, $data_length , $data_precision, $data_scale, $nullable, $comment) = &ora_fetch($csr) ) { $dec=""; if ( $data_type eq "Number" ) { if ( $data_scale ne "0" ) { $dec = $data_scale; } $len = $data_precision; } elsif ( $data_type eq "Date" ) { $len=""; $comment .= " FMT=\"" . $dfmt . "\""; } else { $len = $data_length; } printf OUT_DEX ("% 4d %-20s %-6s%11s%4s %s # %s\n", ++$cnt,$column_name,$data_type,$len,$dec,$nullable,$comment); } &ora_close($csr); close(OUT_DEX); $outname && !$quiet && print STDERR "$NAME: $outname.dex written$outtype\n";}
}
close(STDOUT);
&ora_logoff($lda);
################################################################ END OF PERL SCRIPT
###############################################################
# These next few lines are legal in both Perl and nroff.
.00; # finish .ig 'di \" finish diversion--previous line must be blank .nr nl 0-1 \" fake up transition to first page again .nr % 0 \" start at page 1
'; __END__ ##### From here on it's a standard manual page #####
.PU .TH UNLOADR 1 "04 August 1993" "CSIRO Fisheries" .SH NAME
unloadr - extract data from Oracle table in "merge" format .SH SYNOPSIS
.B unloadr
[
.B -dmlsHhpbqSO]
] [
.B -C[cz]
] [
.BI -Fc
] [
.BI -o\fR[ outfile\fR]
] [
.BI -f fetchlimit
] [
.BI -D dfmt
] [
.BI -w where..
]
.RI < table_name | \fB_at_\fRfile >.. .ll +8 .ad .SH DESCRIPTION .I Unloadr
dumps an Oracle table as an ASCII flat file in "merge" format: each field is comma-delimited and enclosed by quotes. If none of the
.B -dmls
options are set, assume all of these options are set.
.SH OPTIONS .TP .B -d
Create a file describing the structure of .IR table_name,
including any stored table and column comments. Output is to
.IB table_name .dex .PD .TP .B -m
Create ASCII flat file containing all columns in .IB table_name.
Output is to
.IB table_name .mrg . .PD .TP .B -l
Create an Oracle loader control file to reload the merge file.
Output is to
.IB table_name .ctl . .PD .TP .BI -s
Create a file containing
.B SQL
statements to (re)create the table for the extracted data. Output is to
.IB table_name .sql . .PD .TP .B -n
Suppress enclosure of each field by quotation marks. (Normally
.I unloadr
will surround each field in the merge file with double quotes).
.PD .TP .B -H
First line of the output file holds field names, comma-separated.
.PD .TP .B -h
Print a brief help message.
.PD .TP .B -p
Send output to $PRINTCMD, your favorite spooler ("/home/jstander/bin/printw" if not defined).
.PD .TP .B -b
Browse mode, send output to $PAGER (default="more").
.PD .TP .BI -F c
Set column separator in merge file to
.IR c .
Default separator is a comma.
.PD .TP .BI -D dfmt
set date format (default=DD-MON-YYYY HH:24MI).
.PD .TP .BI -f fetchlimit
fetch only <fetchlimit> records from the database.
.PD .TP .BI -o outfile
output is redirected to outfile if present.
.PD .TP .B -O
Output is redirected to stdout
Default is to direct output to <tablename>.mrg.
.PD .TP .B -q
Quiet mode. Don't report actions to STDERR.
.PD .TP .B -S
Dump SQL statement used for merge extraction. No unloading is done.
.PD .TP .B -Cc
Compress output files using
.I compress
utility (if present).
.PD .TP .B -Cz
Compress output files using
.I zip
utility (if present).
.PD .TP .BI -w whereclause
A SQL expression to restrict SELECTed records from table. Note only the expression should be passed, not "WHERE =", see example below.
.PD .TP .I tablename
Name of the table to be unloaded. The column definitions are extracted and a generic SQL statement is automatically constructed to SELECT all columns for unloading, subject only to the restrictions of the
.B -w
option. The user may supply their own SQL statement to select columns for unloading by writing the SQL statement into a file and giving the file name, preceeded by an "\fB_at_\fR" character, in place of the .I tablename
argument.
.PD
.SH NOTE
Any fieldname ending in "COMMENT(S)" is right-trimmed before unloading. Any embedded newlines in the COMMENT(S) field are converted to the meta-char "\fB\\n\fR"
.SH EXAMPLE
Unload all data for cruise number RTMP92-02 from a table called RTMP_OBS_VES_ENTRY. Output will be to the file RTMP9202.ves.
.sp 1 .in+2 .na .B unloadr -w "cruise_num='RTMP92-02'" -o RTMP9202.ves rtmp_obs_ves_entry .in-2 .SH SEE ALSO
unloader(1)
.SH AUTHOR
Jeff.Stander_at_ml.csiro.au
.br
----Cut here---------------------------------------
Stephane Hamel, Sysadmin/DBA *.mais.hydro.qc.ca
Hydro-Quebec TDSB, Montreal, Quebec
E-mail: shamel_at_mais.hydro.qc.ca Voice: (514) 858-7704
Received on Tue Feb 15 1994 - 14:16:28 CET