C# 在C中使用varchar2的PL/SQL assoc数组索引

C# 在C中使用varchar2的PL/SQL assoc数组索引,c#,plsql,C#,Plsql,我有PL/SQL代码: create or replace package TEST_PKG2 as type AssocArray is table of varchar2(20) index by binary_integer; type AssocArray_varchar is table of varchar2(20) index by varchar2(10); --type AssocArray_varchar is table of varchar2(

我有PL/SQL代码:

create or replace 
package        TEST_PKG2 as
  type AssocArray is table of varchar2(20) index by binary_integer;
  type AssocArray_varchar is table of varchar2(20) index by varchar2(10);
  --type AssocArray_varchar is table of varchar2(20) index by integer;

  function assoc_arry_return(Param1 in AssocArray) return AssocArray_varchar;
end TEST_PKG2;

create or replace 
package body        TEST_PKG2 as 
  function assoc_arry_return(Param1 in AssocArray) return AssocArray_varchar
    is
  v_return_value AssocArray_varchar;    
  begin
    v_return_value('name1'):=Param1(1);
    v_return_value('name2'):=Param1(2);
    v_return_value('name3'):=Param1(3);

    return v_return_value;
  end assoc_arry_return;
end TEST_PKG2; 
用于检查pl/sql的控件代码:

set serveroutput on
declare
  assoc_array test_pkg2.AssocArray;
  assoc_array_return test_pkg2.AssocArray_varchar;

begin
  assoc_array(1):='test1';
  assoc_array(2):='test2';
  assoc_array(3):='test3';
  assoc_array_return:= test_pkg2.assoc_arry_return(assoc_array);
  dbms_output.put_line(assoc_array_return.first||' - '||assoc_array_return(assoc_array_return.first));
end;
和执行此函数的C代码:

command = new OracleCommand("TEST_PKG2.assoc_arry_return", OracleConnection);
                command.CommandType = CommandType.StoredProcedure;
                OracleParameter return_value = new OracleParameter();
                return_value.OracleDbType = OracleDbType.Varchar2;
                return_value.Direction = ParameterDirection.ReturnValue;
                return_value.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
                return_value.Size=3;
                return_value.ArrayBindSize = new int[3] { 20, 20, 20 };
                command.Parameters.Add(return_value);

                OracleParameter Param4 = command.Parameters.Add("Param1", OracleDbType.Varchar2);
                Param4.Direction = ParameterDirection.Input;
                Param4.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
                Param4.Value = new string[3] { "First Element", "Second Element", "Third Element" };
                Param4.Size = 3;
                Param4.ArrayBindSize = new int[3] { 20, 20, 20 };
                Param4.ArrayBindStatus = new OracleParameterStatus[3] { OracleParameterStatus.Success, OracleParameterStatus.Success, OracleParameterStatus.Success };
                command.ExecuteNonQuery();
function get_data(...) return STB_JIG_TARLOG_VALUES
  is 
   items STB_JIG_TARLOG_VALUES := STB_JIG_TARLOG_VALUES();
  begin
   items.extend;
   items(1):= STB_JIG_TARLOG_VALUE('key_name','key_value');
   ...
end get_data;
当我使用thic代码执行应用程序时,执行在最后一行终止,错误为ORA-06550:第1行,第15列: PLS-00382:表达式类型错误 ORA-06550:第1行第7列: PL/SQL:忽略语句

这是一个特例,当我使用由varchar2索引的assoc数组时。 当我在整数注释掉的行代码id包上更改包中返回类型的索引时,一切正常

你知道如何在C语言中使用这个软件包吗


Thank's

虽然nor、nor没有明确提及,而且似乎没有人确切知道,但似乎无法绑定varchar2索引关联数组。我通过ODP.NET 10.2从C尝试了它,通过OCI从PHP5.0尝试了它,但没有成功。

所以我尝试使用数据类型对象

在第一步中,我创建数据类型对象

create or replace type STB_JIG_TARLOG_VALUE as object
(
    NAME varchar2(300),
    VALUE varchar2(500)
)

它们不是包装的一部分

现在,我还可以将此类型用作函数的返回类型:

command = new OracleCommand("TEST_PKG2.assoc_arry_return", OracleConnection);
                command.CommandType = CommandType.StoredProcedure;
                OracleParameter return_value = new OracleParameter();
                return_value.OracleDbType = OracleDbType.Varchar2;
                return_value.Direction = ParameterDirection.ReturnValue;
                return_value.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
                return_value.Size=3;
                return_value.ArrayBindSize = new int[3] { 20, 20, 20 };
                command.Parameters.Add(return_value);

                OracleParameter Param4 = command.Parameters.Add("Param1", OracleDbType.Varchar2);
                Param4.Direction = ParameterDirection.Input;
                Param4.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
                Param4.Value = new string[3] { "First Element", "Second Element", "Third Element" };
                Param4.Size = 3;
                Param4.ArrayBindSize = new int[3] { 20, 20, 20 };
                Param4.ArrayBindStatus = new OracleParameterStatus[3] { OracleParameterStatus.Success, OracleParameterStatus.Success, OracleParameterStatus.Success };
                command.ExecuteNonQuery();
function get_data(...) return STB_JIG_TARLOG_VALUES
  is 
   items STB_JIG_TARLOG_VALUES := STB_JIG_TARLOG_VALUES();
  begin
   items.extend;
   items(1):= STB_JIG_TARLOG_VALUE('key_name','key_value');
   ...
end get_data;
最后我们得到返回值,只需选择:

select * from table (get_data(...));
列的名称在STB_JIG_TARLOG_值中定义,向返回值添加值可以是不同的方式,例如循环


从这个查询中获取数据对于DataReader来说没有问题。

上次我检查ODP.NET 10.2时,它无法处理varchar2索引的集合。我怀疑它是否随着时间的推移而改变。顺便说一句,我喜欢riadok和stĺpec-我和同事们讨论了这个话题,我们也得出了同样的结论。在所有手动工作中,仅使用整数索引。使用数据类型对象可以绕过此问题。大概我将尝试一下我一直在设计的.NET->DB接口API,以及我刚刚经历的其他一些项目,它们将结构化数据分解为几个长度相同的标量类型关联数组,然后在DB端将它们重新组合为记录集合或varchar2索引数组。那是在ODP.NET 10的时候。我想我已经看到一些关于在ODP.NET 11+中直接将pls_integer-indexed或varray结构/记录集合从.NET传递到DB的信息,但是,唉,从这里开始,您只能靠自己,我没有ODP.NET 11+的经验来帮助您:-