📄 oracle.pm
字号:
push @Where, "TABLE_NAME LIKE '$TblVal' ESCAPE '\\'"; } if ( defined $TypVal ) { my $table_type_list; $TypVal =~ s/^\s+//; $TypVal =~ s/\s+$//; my @ttype_list = split (/\s*,\s*/, $TypVal); foreach my $table_type (@ttype_list) { if ($table_type !~ /^'.*'$/) { $table_type = "'" . $table_type . "'"; } $table_type_list = join(", ", @ttype_list); } push @Where, "TABLE_TYPE IN ($table_type_list)"; } $Sql .= ' WHERE ' . join("\n AND ", @Where ) . "\n" if @Where; $Sql .= " ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME\n"; } my $sth = $dbh->prepare($Sql) or return undef; $sth->execute or return undef; $sth;} sub primary_key_info { my($dbh, $catalog, $schema, $table) = @_; if (ref $catalog eq 'HASH') { ($schema, $table) = @$catalog{'TABLE_SCHEM','TABLE_NAME'}; $catalog = undef; } my $Sql = <<'SQL';SELECT * FROM( SELECT /*+ RULE*/ NULL TABLE_CAT , c.OWNER TABLE_SCHEM , c.TABLE_NAME TABLE_NAME , c.COLUMN_NAME COLUMN_NAME , c.POSITION KEY_SEQ , c.CONSTRAINT_NAME PK_NAME FROM ALL_CONSTRAINTS p , ALL_CONS_COLUMNS c WHERE p.OWNER = c.OWNER AND p.TABLE_NAME = c.TABLE_NAME AND p.CONSTRAINT_NAME = c.CONSTRAINT_NAME AND p.CONSTRAINT_TYPE = 'P') WHERE TABLE_SCHEM = ? AND TABLE_NAME = ? ORDER BY TABLE_SCHEM, TABLE_NAME, KEY_SEQSQL#warn "@_\n$Sql ($schema, $table)"; my $sth = $dbh->prepare($Sql) or return undef; $sth->execute($schema, $table) or return undef; $sth;} sub foreign_key_info { my $dbh = shift; my $attr = ( ref $_[0] eq 'HASH') ? $_[0] : { 'UK_TABLE_SCHEM' => $_[1],'UK_TABLE_NAME ' => $_[2] ,'FK_TABLE_SCHEM' => $_[4],'FK_TABLE_NAME ' => $_[5] }; my $Sql = <<'SQL'; # XXX: DEFERABILITYSELECT * FROM( SELECT /*+ RULE*/ to_char( NULL ) UK_TABLE_CAT , uk.OWNER UK_TABLE_SCHEM , uk.TABLE_NAME UK_TABLE_NAME , uc.COLUMN_NAME UK_COLUMN_NAME , to_char( NULL ) FK_TABLE_CAT , fk.OWNER FK_TABLE_SCHEM , fk.TABLE_NAME FK_TABLE_NAME , fc.COLUMN_NAME FK_COLUMN_NAME , uc.POSITION ORDINAL_POSITION , 3 UPDATE_RULE , decode( fk.DELETE_RULE, 'CASCADE', 0, 'RESTRICT', 1, 'SET NULL', 2, 'NO ACTION', 3, 'SET DEFAULT', 4 ) DELETE_RULE , fk.CONSTRAINT_NAME FK_NAME , uk.CONSTRAINT_NAME UK_NAME , to_char( NULL ) DEFERABILITY , decode( uk.CONSTRAINT_TYPE, 'P', 'PRIMARY', 'U', 'UNIQUE') UNIQUE_OR_PRIMARY FROM ALL_CONSTRAINTS uk , ALL_CONS_COLUMNS uc , ALL_CONSTRAINTS fk , ALL_CONS_COLUMNS fc WHERE uk.OWNER = uc.OWNER AND uk.CONSTRAINT_NAME = uc.CONSTRAINT_NAME AND fk.OWNER = fc.OWNER AND fk.CONSTRAINT_NAME = fc.CONSTRAINT_NAME AND uk.CONSTRAINT_TYPE IN ('P','U') AND fk.CONSTRAINT_TYPE = 'R' AND uk.CONSTRAINT_NAME = fk.R_CONSTRAINT_NAME AND uk.OWNER = fk.R_OWNER AND uc.POSITION = fc.POSITION) WHERE 1 = 1SQL my @BindVals = (); while ( my ( $k, $v ) = each %$attr ) { if ( $v ) { $Sql .= " AND $k = ?\n"; push @BindVals, $v; } } $Sql .= " ORDER BY UK_TABLE_SCHEM, UK_TABLE_NAME, FK_TABLE_SCHEM, FK_TABLE_NAME, ORDINAL_POSITION\n"; my $sth = $dbh->prepare( $Sql ) or return undef; $sth->execute( @BindVals ) or return undef; $sth; } sub column_info { my $dbh = shift; my $attr = ( ref $_[0] eq 'HASH') ? $_[0] : { 'TABLE_SCHEM' => $_[1],'TABLE_NAME' => $_[2],'COLUMN_NAME' => $_[3] }; my($typecase,$typecaseend) = ('',''); if (ora_server_version($dbh)->[0] >= 8) { $typecase = <<'SQL';CASE WHEN tc.DATA_TYPE LIKE 'TIMESTAMP% WITH% TIME ZONE' THEN 95 WHEN tc.DATA_TYPE LIKE 'TIMESTAMP%' THEN 93 WHEN tc.DATA_TYPE LIKE 'INTERVAL DAY% TO SECOND%' THEN 110 WHEN tc.DATA_TYPE LIKE 'INTERVAL YEAR% TO MONTH' THEN 107ELSESQL $typecaseend = 'END'; } my $Sql = <<"SQL";SELECT * FROM( SELECT /*+ RULE*/ to_char( NULL ) TABLE_CAT , tc.OWNER TABLE_SCHEM , tc.TABLE_NAME TABLE_NAME , tc.COLUMN_NAME COLUMN_NAME , $typecase decode( tc.DATA_TYPE , 'MLSLABEL' , -9106 , 'ROWID' , -9104 , 'UROWID' , -9104 , 'BFILE' , -4 -- 31? , 'LONG RAW' , -4 , 'RAW' , -3 , 'LONG' , -1 , 'UNDEFINED', 0 , 'CHAR' , 1 , 'NCHAR' , 1 , 'NUMBER' , decode( tc.DATA_SCALE, NULL, 8, 3 ) , 'FLOAT' , 8 , 'VARCHAR2' , 12 , 'NVARCHAR2', 12 , 'BLOB' , 30 , 'CLOB' , 40 , 'NCLOB' , 40 , 'DATE' , 93 , NULL ) $typecaseend DATA_TYPE -- ... , tc.DATA_TYPE TYPE_NAME -- std.? , decode( tc.DATA_TYPE , 'LONG RAW' , 2147483647 , 'LONG' , 2147483647 , 'CLOB' , 2147483647 , 'NCLOB' , 2147483647 , 'BLOB' , 2147483647 , 'BFILE' , 2147483647 , 'NUMBER' , decode( tc.DATA_SCALE , NULL, 126 , nvl( tc.DATA_PRECISION, 38 ) ) , 'FLOAT' , tc.DATA_PRECISION , 'DATE' , 19 , tc.DATA_LENGTH ) COLUMN_SIZE , decode( tc.DATA_TYPE , 'LONG RAW' , 2147483647 , 'LONG' , 2147483647 , 'CLOB' , 2147483647 , 'NCLOB' , 2147483647 , 'BLOB' , 2147483647 , 'BFILE' , 2147483647 , 'NUMBER' , nvl( tc.DATA_PRECISION, 38 ) + 2 , 'FLOAT' , 8 -- ? , 'DATE' , 16 , tc.DATA_LENGTH ) BUFFER_LENGTH , decode( tc.DATA_TYPE , 'DATE' , 0 , tc.DATA_SCALE ) DECIMAL_DIGITS -- ... , decode( tc.DATA_TYPE , 'FLOAT' , 2 , 'NUMBER' , decode( tc.DATA_SCALE, NULL, 2, 10 ) , NULL ) NUM_PREC_RADIX , decode( tc.NULLABLE , 'Y' , 1 , 'N' , 0 , NULL ) NULLABLE , cc.COMMENTS REMARKS , tc.DATA_DEFAULT COLUMN_DEF -- Column is LONG! , decode( tc.DATA_TYPE , 'MLSLABEL' , -9106 , 'ROWID' , -9104 , 'UROWID' , -9104 , 'BFILE' , -4 -- 31? , 'LONG RAW' , -4 , 'RAW' , -3 , 'LONG' , -1 , 'UNDEFINED', 0 , 'CHAR' , 1 , 'NCHAR' , 1 , 'NUMBER' , decode( tc.DATA_SCALE, NULL, 8, 3 ) , 'FLOAT' , 8 , 'VARCHAR2' , 12 , 'NVARCHAR2', 12 , 'BLOB' , 30 , 'CLOB' , 40 , 'NCLOB' , 40 , 'DATE' , 9 -- not 93! , NULL ) SQL_DATA_TYPE -- ... , decode( tc.DATA_TYPE , 'DATE' , 3 , NULL ) SQL_DATETIME_SUB -- ... , to_number( NULL ) CHAR_OCTET_LENGTH -- TODO , tc.COLUMN_ID ORDINAL_POSITION , decode( tc.NULLABLE , 'Y' , 'YES' , 'N' , 'NO' , NULL ) IS_NULLABLE FROM ALL_TAB_COLUMNS tc , ALL_COL_COMMENTS cc WHERE tc.OWNER = cc.OWNER AND tc.TABLE_NAME = cc.TABLE_NAME AND tc.COLUMN_NAME = cc.COLUMN_NAME) WHERE 1 = 1SQL my @BindVals = (); while ( my ( $k, $v ) = each %$attr ) { if ( $v ) { $Sql .= " AND $k LIKE ? ESCAPE '\\'\n"; push @BindVals, $v; } } $Sql .= " ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION\n"; my $sth = $dbh->prepare( $Sql ) or return undef; $sth->execute( @BindVals ) or return undef; $sth; } sub type_info_all { my ($dbh) = @_; my $version = ( ora_server_version($dbh)->[0] < DBD::Oracle::ORA_OCI() ) ? ora_server_version($dbh)->[0] : DBD::Oracle::ORA_OCI(); my $vc2len = ( $version < 8 ) ? "2000" : "4000"; my $type_info_all = [ { TYPE_NAME => 0, DATA_TYPE => 1, COLUMN_SIZE => 2, LITERAL_PREFIX => 3, LITERAL_SUFFIX => 4, CREATE_PARAMS => 5, NULLABLE => 6, CASE_SENSITIVE => 7, SEARCHABLE => 8, UNSIGNED_ATTRIBUTE => 9, FIXED_PREC_SCALE => 10, AUTO_UNIQUE_VALUE => 11, LOCAL_TYPE_NAME => 12, MINIMUM_SCALE => 13, MAXIMUM_SCALE => 14, SQL_DATA_TYPE => 15, SQL_DATETIME_SUB => 16, NUM_PREC_RADIX => 17, INTERVAL_PRECISION => 18, }, [ "LONG RAW", SQL_LONGVARBINARY, 2147483647,"'", "'", undef, 1,0,0,undef,0,undef, "LONG RAW", undef,undef,SQL_LONGVARBINARY,undef,undef,undef, ], [ "RAW", SQL_VARBINARY, 2000, "'", "'", "max length", 1,0,3,undef,0,undef, "RAW", undef,undef,SQL_VARBINARY, undef,undef,undef, ], [ "LONG", SQL_LONGVARCHAR, 2147483647,"'", "'", undef, 1,1,0,undef,0,undef, "LONG", undef,undef,SQL_LONGVARCHAR, undef,undef,undef, ], [ "CHAR", SQL_CHAR, 2000, "'", "'", "max length", 1,1,3,undef,0,0, "CHAR", undef,undef,SQL_CHAR, undef,undef,undef, ], [ "DECIMAL", SQL_DECIMAL, 38, undef,undef, "precision,scale",1,0,3,0, 0,0, "DECIMAL", 0, 38, SQL_DECIMAL, undef,10, undef, ], [ "DOUBLE PRECISION",SQL_DOUBLE, 15, undef,undef, undef, 1,0,3,0, 0,0, "DOUBLE PRECISION",undef,undef,SQL_DOUBLE, undef,10, undef, ], [ "DATE", SQL_TYPE_TIMESTAMP,19, "'", "'", undef, 1,0,3,undef,0,0, "DATE", 0, 0, SQL_DATE, 3, undef,undef, ], [ "VARCHAR2", SQL_VARCHAR, $vc2len, "'", "'", "max length", 1,1,3,undef,0,0, "VARCHAR2", undef,undef,SQL_VARCHAR, undef,undef,undef, ], ]; push @$type_info_all, [ "BLOB", SQL_LONGVARBINARY, 2147483647,"'", "'", undef, 1,1,0,undef,0,undef, "BLOB", undef,undef,SQL_LONGVARBINARY,undef,undef,undef, ], [ "BFILE", SQL_LONGVARBINARY, 2147483647,"'", "'", undef, 1,1,0,undef,0,undef, "BFILE", undef,undef,SQL_LONGVARBINARY,undef,undef,undef, ], [ "CLOB", SQL_LONGVARCHAR, 2147483647,"'", "'", undef, 1,1,0,undef,0,undef, "CLOB", undef,undef,SQL_LONGVARCHAR, undef,undef,undef, ], if $version >= 8; return $type_info_all; } sub plsql_errstr { # original version thanks to Bob Menteer my $sth = shift->prepare_cached(q{ SELECT name, type, line, position, text FROM user_errors ORDER BY name, type, sequence }) or return undef; $sth->execute or return undef; my ( @msg, $oname, $otype, $name, $type, $line, $pos, $text ); $oname = $otype = 0; while ( ( $name, $type, $line, $pos, $text ) = $sth->fetchrow_array ) { if ( $oname ne $name || $otype ne $type ) { push @msg, "Errors for $type $name:"; $oname = $name; $otype = $type; } push @msg, "$line.$pos: $text"; } return join( "\n", @msg ); } # # note, dbms_output must be enabled prior to usage # sub dbms_output_enable { my ($dbh, $buffersize) = @_; $buffersize ||= 20000; # use oracle 7.x default $dbh->do("begin dbms_output.enable(:1); end;", undef, $buffersize); } sub dbms_output_get { my $dbh = shift; my $sth = $dbh->prepare_cached("begin dbms_output.get_line(:l, :s); end;") or return; my ($line, $status, @lines); # line can be greater that 255 (e.g. 7 byte date is expanded on output) $sth->bind_param_inout(':l', \$line, 400, { ora_type => 1 }); $sth->bind_param_inout(':s', \$status, 20, { ora_type => 1 }); if (!wantarray) { $sth->execute or return undef; return $line if $status eq '0'; return undef; } push @lines, $line while($sth->execute && $status eq '0'); return @lines; } sub dbms_output_put { my $dbh = shift; my $sth = $dbh->prepare_cached("begin dbms_output.put_line(:1); end;") or return; my $line; foreach $line (@_) { $sth->execute($line) or return; } return 1; } sub dbms_msgpipe_get { my $dbh = shift; my $sth = $dbh->prepare_cached(q{ begin dbms_msgpipe.get_request(:returnpipe, :proc, :param); end; }) or return; my $msg = ['','','']; $sth->bind_param_inout(":returnpipe", \$msg->[0], 30); $sth->bind_param_inout(":proc", \$msg->[1], 30); $sth->bind_param_inout(":param", \$msg->[2], 4000); $sth->execute or return undef; return $msg; } sub dbms_msgpipe_ack {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -