【问题标题】:Pass an XML file as a parameter to an Oracle stored procedure将 XML 文件作为参数传递给 Oracle 存储过程
【发布时间】:2023-03-22 04:47:01
【问题描述】:

我正在尝试使用 Perl 脚本将 XML 文件作为 XMLType 的参数传递给 Oracle 存储过程。

我正在使用 Perl DBIDBD::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();

【问题讨论】:

  • 你不应该使用 & 符号 &amp; 来调用 Perl 子程序;大约二十年来,这一直不是一个好的做法。无论您在哪里学习,这都是非常过时的,您应该找到更新的来源。除了use strict,你还应该use warnings 'all',并且你的包名和它们的关联文件应该大写,所以util::File应该是Util::File等等。
  • 感谢 Borodin 的建议,我一定会做出这些改变。

标签: xml oracle perl stored-procedures


【解决方案1】:

我认为首先你应该将一个文件写入变量,如果它不是那么大。接下来,您应该指定绑定,我将它们称为过程参数: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(  );
... 

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    • 2014-04-16
    • 2012-11-23
    • 1970-01-01
    相关资源
    最近更新 更多