passing PHP array to Oracle Stored Proc (PLS-00306: wrong number or types of arguments)

余生颓废 提交于 2019-12-12 15:29:21

问题


Using PHP 5.3.2 and Oracle 11G, I'm trying to pass an array from PHP into an oracle stored proc. Here is my 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;

The Query:

  $sql = "begin txa.upsert_txa_compliance_slct(:my_array); end;";

And the PHP Code I've tried to bind the array and execute :

First:

<?

$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);

?>

Which generates this error:

PLS-00306: wrong number or types of arguments in call to 'UPSERT_TXA_COMPLIANCE_SLCT'

I'm clearly passing 1 arg. So, what's wrong with/how do I fix the type issue?

Additionally I found this

http://www.oracle.com/technetwork/articles/seliverstov-multirows-098120.html

And tried it the old way using oci collection like so:

 $collection = oci_new_collection($this->conn,"NUM_ARRAY");

After I changed my oracle type to this:

create or replace type NUM_ARRAY as varray(100) of number;

I got this error:

oci_new_collection(): ORA-22318: input type is not an array type

Any help would be MUCH appreciated.

EDIT 7:08PM ET Aug 14, 2014

I changed my php oci_bind function call to use SQLT_NUM as the type. This had no impact. Then I changed my package to include:

type num_array is table of number index by binary_integer;

( i also dropped the original num_array from my schema )

This change made it possible to pass my array to the stored proc, but then I can't use the array as a nested table like so:

delete 
  from my_table
 where id not in (select column_value from table(v_compl_id_array));

I get this error when i try to compile the package body with that statement in it:

PL/SQL: ORA-22905: cannot access rows from a non-nested table item

And all the documentation tells me to return to the schema level type? But when I do I get that other error. I know I can find another way to do this using a loop over my pl/sql array, but I would really love to be able to use that schema level type.


回答1:


The answer is this. You can't use a globally created or schema level type as a parameter to a stored procedure. PHP's oci_bind_array_by_name just doesn't seem to work with globally created types, but you need the globally created type to be able to use your array as a nested table in subselects. So.... here is how I got this to work. I'm MORE THAN HAPPY TO HEAR OTHER SOLUTIONS!! but for now, here's what I did.

-- 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));


来源:https://stackoverflow.com/questions/25310968/passing-php-array-to-oracle-stored-proc-pls-00306-wrong-number-or-types-of-arg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!