我正在尝试使用Perl脚本将XML文件作为XMLType参数传递给Oracle存储过程。
我使用的是Perl DBI
和DBD::Oracle
模块。
我做了我的研究并找到了如何做到这一点,但我不知道如何把所有东西放在一起以达到我想要的目的。
我是否将文件中包含的XML数据作为字符串或CLOB传递给$xml
?
大多数XML解析和表更新都在存储过程中。
这是我有多远。我没有尝试执行脚本,因为我知道它不完整。
#!/usr/local/bin/perl
###############################################################################
# File Name: load_data.pl
# Description: Reads an input XML file and populates data into tables
use strict;
use Getopt::Std;
use DBI;
use DBD::Oracle qw(:ora_types);
# Properties file parser
#
use util::File;
use use util::DotConfigProperties;
# Generic Utilities
#
use util::GenericUtils qw(getEnv isPath isFile trim );
# Flush output buffers
#
$| = 1;
#############################################################################
# Local Variables
my %args = (
AutoCommit => 0,
RaiseError => 1,
PrintError => 1
);
my $aConfig = &isFile( &getEnv('aConfig') );
# Get the DB properties and open the database connection
#
my $propObj = new util::DotConfigProperties;
my $a_prop = new util::File($aConfig);
$propObj->load($a_prop);
my $dbSid = trim($propObj->getProperty('Database'));
my $user = trim($propObj->getProperty('Username'));
my $password = trim($propObj->getProperty('Password'));
my $dbh = DBI->connect("dbi:Oracle:$dbSid", $user, $password, \%args) or croak("Couldn't connect to database: $dbSid" . DBI->errstr);
#############################################################################
# Input file
open(RFILE,"@ARGV[0]") or die("Unable to open read file");
#
# Read in the data from input file
#
while (<RFILE>) {
$sth = $dbh->prepare( "BEGIN My_Procedure (p_xml in xmltype,
p_out_xml out xmltype,
p_message out varchar2,
p_result out integer); END;" );
$sth->bind_param("p_xml", **$xml**, { ora_type => ORA_XMLTYPE });
$sth->bind_param_inout( ?, \$p_out_xml, ? ); --**I am not sure what to put in place of the question marks?**
$sth->bind_param_inout( ?, \$p_message, ? );
$sth->bind_param_inout( ?, \$p_result, ? );
$sth->execute( );
}
$dbh->commit();
###############################################################################
# Close anything open and exit
$dbh->disconnect();
exit;
我做了@MichaelPiankov提到的修改并进行了一些修改。这是结果
my $xml;
while (<RFILE>) {
$xml.= $_;
}
my $sth = $dbh->prepare( "BEGIN My_Procedure(:p_xml,
:p_out_xml,
:p_message,
:p_result); END;" );
$sth->bind_param(":p_xml", $xml, { ora_type => ORA_XMLTYPE });
my $p_out_xml;
my $p_message;
my $p_result;
$sth->bind_param_inout(":p_out_xml", \$p_out_xml, { ora_type => ORA_XMLTYPE } );
$sth->bind_param_inout(":p_message", \$p_message, { ora_type => ORA_VARCHAR2 } );
$sth->bind_param_inout(":p_result", \$p_result, { ora_type => ORA_NUMBER } );
$sth->execute( );
print "Out_XML: $p_out_xml\n";
print "Message: $p_message\n";
print "Result: $p_result\n";
$dbh->commit();
###############################################################################
# Close anything open and exit
$dbh->disconnect();
exit;
DBD::Oracle::st execute failed: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'My_Procedure'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored (DBD ERROR: error possibly near <*> indicator at char 6 in 'BEGIN <*>My_Procedure(:p_xml,
:p_out_xml,
:p_message,
:p_result); END;') [for Statement "BEGIN My_Procedure(:p_xml,
:p_out_xml,
:p_message,
:p_result); END;" with ParamValues: :p_xml=OCIXMLTypePtr=SCALAR(0x9085170), :p_message=undef, :p_out_xml=undef, :p_result=undef] at load_tables.pl line 45, <RFILE> line 46947.
Out_XML:
Message:
Result:
commit ineffective with AutoCommit enabled at load_tables.pl line 51, <RFILE> line 46947.
我最终删除了out参数并成功加载了XML文件,这是我的目标,因为这是测试一些存储过程代码的一部分。我确实想赞扬@MichaelPiankov,因为他的代码帮助我加载了文件。
my $xml;
while (<RFILE>) {
$xml.= $_;
}
my $sth = $dbh->prepare( "BEGIN My_Procedure(:p_xml); END;" );
$sth->bind_param(":p_xml", $xml, { ora_type => ORA_XMLTYPE });
$sth-> execute();
答案 0 :(得分:0)
我认为首先你应该把文件写成变量,如果不是那么大的话。接下来你应该指定绑定我把它们称为过程参数:p_xml,:p_out_xml,:p_message,:p_result,但你可以使用任何名称。你应该为输出值创建一个变量\ $ p_out_xml,\ $ p_message \ $ p_result
...
my $xml;
while (<RFILE>) {
$xml.= $_;
}
$sth = $dbh->prepare( "BEGIN My_Procedure (:p_xml,
:p_out_xml,
:p_message,
:p_result); END;" );
$sth->bind_param("p_xml", $xml, { ora_type => ORA_XMLTYPE });
my $p_out_xml;
my $p_message;
my $p_result;
$sth->bind_param_inout("p_out_xml", \$p_out_xml, { ora_type => ORA_XMLTYPE } );
$sth->bind_param_inout("p_message", \$p_message );
$sth->bind_param_inout("p_result", \$p_result);
$sth->execute( );
...