将PHP数组传递给Oracle存储过程(PLS-00306:参数的数量或类型错误)
使用PHP5.3.2和Oracle11g,我试图将一个数组从PHP传递到Oracle存储过程中。以下是我的PL/SQL:将PHP数组传递给Oracle存储过程(PLS-00306:参数的数量或类型错误),php,sql,arrays,oracle,oracle11g,Php,Sql,Arrays,Oracle,Oracle11g,使用PHP5.3.2和Oracle11g,我试图将一个数组从PHP传递到Oracle存储过程中。以下是我的PL/SQL: create or replace type NUM_ARRAY as table of number; create or replace package txa as procedure upsert_txa_compliance_slct( v_compl_id_array in num_array); end txa; create or repl
create or replace type NUM_ARRAY as table of number;
create or replace package txa as
procedure upsert_txa_compliance_slct( v_compl_id_array in num_array);
end txa;
create or replace package body txa as
procedure upsert_txa_compliance_slct(v_compl_id_array in num_array)
is
begin
.
. -- sql code removed for brevity. package and body compile no errors
.
end upsert_txa_compliance_slct;
end;
查询:
$sql = "begin txa.upsert_txa_compliance_slct(:my_array); end;";
我尝试绑定数组并执行的PHP代码:
第一:
<?
$this->conn = ociplogon($dbuser, $dbpass, $dbname);
$this->commit_mode = OCI_COMMIT_ON_SUCCESS;
$this->sth = @ociparse($this->conn, $sql);
oci_bind_array_by_name($this->sth,
':my_array',
$my_array,
count($my_array),
-1,
SQLT_CHR);
$r = @ociexecute($this->sth, $this->commit_mode);
?>
将oracle类型更改为以下类型后:
create or replace type NUM_ARRAY as varray(100) of number;
我得到了这个错误:
oci_new_collection():ORA-22318:输入类型不是数组类型
任何帮助都将不胜感激
编辑2014年8月14日东部时间晚上7:08
我更改了php oci_bind函数调用,将SQLT_NUM用作类型。这没有任何影响。然后我更改了我的包,包括:
type num_array is table of number index by binary_integer;
(我还从模式中删除了原始num_数组)
此更改使我可以将数组传递给存储的进程,但我不能将数组用作嵌套表,如下所示:
delete
from my_table
where id not in (select column_value from table(v_compl_id_array));
当我试图编译包含该语句的包体时,会出现以下错误:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
所有文档都告诉我返回到模式级别类型?但当我这样做的时候,我得到了另一个错误。我知道我可以通过pl/sql数组上的循环找到另一种方法来实现这一点,但我非常希望能够使用这种模式级别的类型。答案是这样的。不能将全局创建的或架构级别的类型用作存储过程的参数。PHP的oci_bind_array_by_name似乎无法处理全局创建的类型,但您需要全局创建的类型才能将数组用作子选择中的嵌套表。所以这是我如何让它工作的。我非常高兴听到其他解决方案!!但现在,我所做的就是这样
-- globally create a type table of number
create or replace type num_array is table of number;
-- in my package i created an internal type table of number
type i_num_array is table of number index by binary_integer;
-- i then used i_num_array (internal type) as the type for my IN parameter to the procedure
upsert_TXA_compliance_slct( v_compl_id_array in i_num_array)
-- in my procedure i also created a variable that is the type of my globally created type
v_num_array num_array := num_array();
-- then i populated that variable in a loop inside my procedure with the values in my IN param
for i in 1 .. v_compl_id_array.count
loop
v_num_array.extend(1);
v_num_array(i) := v_compl_id_array(i);
end loop;
-- then i used v_num_array as my nested table so this now works:
delete from my_table where id in (select * from table(v_num_array));
-- globally create a type table of number
create or replace type num_array is table of number;
-- in my package i created an internal type table of number
type i_num_array is table of number index by binary_integer;
-- i then used i_num_array (internal type) as the type for my IN parameter to the procedure
upsert_TXA_compliance_slct( v_compl_id_array in i_num_array)
-- in my procedure i also created a variable that is the type of my globally created type
v_num_array num_array := num_array();
-- then i populated that variable in a loop inside my procedure with the values in my IN param
for i in 1 .. v_compl_id_array.count
loop
v_num_array.extend(1);
v_num_array(i) := v_compl_id_array(i);
end loop;
-- then i used v_num_array as my nested table so this now works:
delete from my_table where id in (select * from table(v_num_array));