【问题标题】:passing PHP array to Oracle Stored Proc (PLS-00306: wrong number or types of arguments)将 PHP 数组传递给 Oracle 存储过程(PLS-00306:错误的参数数量或类型)
【发布时间】:2014-10-08 06:39:05
【问题描述】:

使用 PHP 5.3.2 和 Oracle 11G,我试图将数组从 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 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 )

这个改变可以将我的数组传递给存储过程,但是我不能像这样将数组用作嵌套表:

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 sql arrays oracle oracle11g


    【解决方案1】:

    答案是这样的。您不能将全局创建的或架构级别的类型用作存储过程的参数。 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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 2018-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多