使用PHP 5.3.2和Oracle 11G,我试图将数组从PHP传递到oracle存储的proc中。这是我的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 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); ?>
会产生此错误:
PLS-00306:调用“ UPSERT_TXA_COMPLIANCE_SLCT”时参数的数量或类型错误
我显然传递了1个参数。那么,这是什么问题/如何解决类型问题?
另外我发现了这个
http://www.oracle.com/technetwork/articles/seliverstov- multirows-098120.html
并使用oci收集以旧方式进行了尝试,如下所示:
$collection = oci_new_collection($this->conn,"NUM_ARRAY");
在将我的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_array)
此更改使将数组传递给存储的proc成为可能,但是这样我就不能将数组用作嵌套表,如下所示:
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));