in reply to Re^3: CREATE TABLE DDL from DBI Statement
in thread CREATE TABLE DDL from DBI Statement
CountZero,
I had a chance to try the SQL::Translator but I wasn't able to get any results. :| The DB2 system I'm hitting (on a mainframe) has 10 main subsystems, each with 50-100 schemas, each with 100-200 tables. In the past I've used tools like hibernate to reverse-engineer schemas but it also takes forever to run. I've got very low priority on the system which doesn't help either.
With that in mind, I did end up rolling my own little snippet.
use DBI qw(:sql_types); my $type_map = { DBI::SQL_DATE => {'name'=>'DATE'} , DBI::SQL_TYPE_TIMESTAMP => {'name'=>'TIMESTAMP'} , DBI::SQL_CHAR => {'name'=>'CHAR','use_precision'=>'1 +'} , DBI::SQL_VARCHAR => {'name'=>'VARCHAR','use_precision'= +>'1'}, DBI::SQL_INTEGER => {'name'=>'INT'}, DBI::SQL_NUMERIC => {'name'=>'NUMERIC','use_precision'= +>'1', 'use_scale'=>'1'}, }; sub ddl_create_from_statement { my $param_ref = shift; my $statement = $param_ref->{'statement'}; my $tablename = $param_ref->{'tablename'}; my $colname_ref = $statement->{NAME}; my $type_ref = $statement->{TYPE}; my $precision_ref = $statement->{PRECISION}; my $scale_ref = $statement->{SCALE}; my $nullable_ref = $statement->{NULLABLE}; my @fields; for ( my $i = 0 ; $i < @{$colname_ref} ; $i++ ) { ## Look the DDL word for the DBI::sql_type in $type_map my $ddl_column = $colname_ref->[$i] . ' ' . $type_map->{$t +ype_ref->[$i]}{'name'}; my @precscale; ## Determine if we need precision and scale if ($type_map->{$type_ref->[$i]}{'use_precision'}) { push @precscale, $precision_ref->[$i]; } if ($type_map->{$type_ref->[$i]}{'use_scale'}) { push @precscale, $scale_ref->[$i]; } if (@precscale) { $ddl_column .= '(' . join(',',@precscale) . ')'; } if (! $nullable_ref->[$i] ) { $ddl_column .= ' NOT NULL'; } push @fields, "$ddl_column"; } return "CREATE TABLE $tablename (\n" . join(",\n", @fields) . +"\n)"; }
The heart of it is a hash lookup that maps the DBI::sql_type to the DDL word, and determines if scale&precision are applicable. I just did the first few types (CHAR,VARCHAR,INT, ...) but I know there are more to add. Once I get it more complete maybe I should post a snippet. (?)
Thanks for your time and your advice!
Regards,
Kurt
|
|---|