Q9.14: ddl_insert.pl
In order to use this script you must have Sybperl installed -- see Q9.4 for more information.
#!/usr/local/bin/perl
# Author: Vincent Yin (umyin@mctrf.mb.ca) Aug 1994 Last Modified: May 1996
chomp($basename = `basename $0`);
$usage = <', analyses the data
and table structure, then prints out a bunch of
insert values ( ... )
statements that would re-populate the table. It's an alternative
to `bcp'. `bcp' has its limitations (e.g. one often needs to turn on
'select into/bulk copy' option in the database before running bcp.)
Table names are matched to with Transact-SQL's LIKE clause.
When more than one pattern is specified on command line, the LIKE
clauses are OR'ed. In any case, the LIKE clause(s) is logged to
the beginning of the output as a comment, so that you'll see how this
program interprets the command line.
The SQL script is printed to stdout. Since it only prints out the SQL
but doesn't submit it to the SQL server, this procedure is safe to run.
It doesn't modify database in any way.
EXAMPLES
To print this usage page:
% $basename
To print SQL that populates the table master..sysobjects and systypes:
% $basename master userid passwd 'sysobjects' 'systypes'
To print SQL that populates all system tables in master db:
% $basename master userid passwd 'sys%'
BUGS
Embedded line breaks in strings are allowed in Sybase's isql, but not
allowed in SQLAnywhere's isql. So this script converts embedded line
breaks (both DOS styled and UNIX styled) to blank characters.
EOF
$batchsize = 10; # The number of INSERTs before a `go' is issued.
# This is to make the output compact.
# .................... No change needed below this line ........................
use Sybase::DBlib;
die $usage unless $#ARGV >= 3;
($db, $user, $passwd, @pattern) = @ARGV;
$likeclause = &sql_pattern_to_like_clause('name', @pattern);
print <{dbNullIsUndef} = 1;
$dbh->dbuse($db);
# Get the list of tables.
$tablelist = $dbh->sql("select name from sysobjects
where type in ('S','U') and $likeclause
order by name
");
foreach $tableref (@$tablelist) {
$table = @$tableref[0];
print "\n\n/*.............. $table ...............*/\n";
print "-- ", `date`, "\n";
print "declare \@d datetime\n";
print "select \@d = getdate()\n";
print "print ' %1! $table', \@d\ngo\n\n";
print "truncate table $table -- Lookout !!!!!!\ngo\n\n";
$dbh->dbcmd("select * from $table");
$dbh->dbsqlexec;
$dbh->dbresults;
while (@row = $dbh->dbnextrow()) {
print "insert $table values(";
for ($i=0; $i <= $#row; $i++) { # build the INSERT statement
# Analyse datatype to decide if this column needs to be quoted.
$coltype = $dbh->dbcoltype($i+1);
if (!defined($row[$i])) {
print 'NULL'; # Never quote NULL regardless of datatype
}
elsif ($coltype==35 or $coltype==39 or $coltype==47 or
$coltype==58 or $coltype==61 or $coltype==111 ){
# See systypes.type/name for explanation of $coltype.
$row[$i] =~ s/\r|\n/ /g; # Handles both DOS and UNIX line breaks
$row[$i] =~ s/"/""/g; # Stuff double quotes
print "\"" . $row[$i] . "\"";
}
else {
print $row[$i];
}
print ", " unless $i == $#row;
}
print ")\n"; # wrap up the INSERT statement.
# print `go' at every $batchsize interval.
print "go\n" unless $dbh->DBCURROW % $batchsize;
}
print "\ngo\n\n"; # print a `go' after the entire table is done.
print "-- ### End for $table: rowcount = ", $dbh->DBCURROW, "\n";
}
# ................................. sub ........................................
sub main'sql_pattern_to_like_clause {
local($field_name, @pattern) = @_;
$like_clause = "\t( 1 = 0 ";
foreach (@pattern) {
$like_clause .= "\n or $field_name like '" . $_ . "' ";
}
$like_clause .= "\n\t) \n";
}