C#2010,ODP.net,调用存储过程传递数组

我有一个PL / SQL存储过程,需要4个输入。 其中一个输入是关联数组(Oracle Type:VARCHAR2表(1)PLS_INTEGER索引)。

我想要一个C#程序,用适当的输入调用这个存储过程,包括关联数组。

我正在使用ODP.net 11.2与Visual C#2010 Express和Oracle 11gR2。

我找不到任何关于如何从C#传递数组到pl / sql过程的好例子。 有谁可以举个例子? 以下Oracle文档确切地告诉我错误的数字或参数类型。

我的C#代码:

OracleCommand cmd = new OracleCommand("begin sdg_test.sdg_test2(:1); end;", conn); OracleParameter Param1 = cmd.Parameters.Add("1", OracleDbType.Varchar2); Param1.Direction = ParameterDirection.Input; Param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray; Param1.Value = new string[22] { "Y", "Y", "N", "Y", "N", "Y", "Y", "Y", "Y", "Y", "N", "Y", "N", "Y", "Y", "Y", "Y", "Y", "N", "Y", "N", "Y" }; Param1.Size = 22; Param1.ArrayBindSize = new int[22] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; cmd.ExecuteNonQuery(); conn.Close(); conn.Dispose(); 

我的所有程序都记录了一条消息。 我只是想让这个概念起作用。

你可以从(更简单的方式)开始:

 List idList = yourObjectList; List nameList = yourObjectList; using (OracleConnection oraconn = new OracleConnection()) { oraconn.ConnectionString = "Your_Connection_string"; using (OracleCommand oracmd = new OracleCommand()) { oracmd.Connection = oraconn; oracmd.CommandType = CommandType.StoredProcedure; oracmd.CommandText = "Your_Procedura_name"; oraconn.Open(); // To use ArrayBinding, you need to set ArrayBindCount oracmd.BindByName = true; oracmd.ArrayBindCount = idList.Count; // Instead of single values, we pass arrays of values as parameters oracmd.Parameters.Add("ids", OracleDbType.Int32, oyourObjectList.ToArray(), ParameterDirection.Input); oracmd.Parameters.Add("names", OracleDbType.Varchar2, oyourObjectList.ToArray(), ParameterDirection.Input); oracmd.ExecuteNonQuery(); oraconn.Close(); } } 

然后,在db中添加package / procedure:

 PROCEDURE Your_Procedure_name( name IN VARCHAR2, id IN NUMBER ) IS BEGIN INSERT INTO your_table VALUES( id, name); END Your_Procedure_name; 

另一种选择是:

 using (OracleConnection oraconn = new OracleConnection()) { oraconn.ConnectionString = "Your_Connection_string"; using (OracleCommand cmd = new OracleCommand()) { cmd.Connection = oraconn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "Your_Procedure_name"; oraconn.Open(); OracleParameter idParam = new OracleParameter("i_idList", OracleDbType.Int32, ParameterDirection.Input); idParam.CollectionType = OracleCollectionType.PLSQLAssociativeArray; idParam.Value = idList.ToArray(); idParam.Size = idList.Count; OracleParameter nameParam = new OracleParameter("i_nameList", OracleDbType.Varchar2, ParameterDirection.Input); nameParam.CollectionType = OracleCollectionType.PLSQLAssociativeArray; nameParam.Value = nameList.ToArray(); nameParam.Size = nameList.Count; // You need this param for output cmd.Parameters.Add("ret", OracleDbType.RefCursor).Direction = ParameterDirection.Output; cmd.Parameters.Add(idParam); cmd.Parameters.Add(nameParam); conn.Open(); //If you need to read results ... using (OracleDataReader dr = cmd.ExecuteReader()) { while (dr.Read()) { ... } } conn.Close(); } } 

但它更复杂,因为您需要为存储过程定义新类型,例如

 TYPE integer_list IS TABLE OF Your_table.id_column%TYPE INDEX BY BINARY_INTEGER; // same for names 

创建类似的模式级类型

 create or replace TYPE T_ID_TABLE is table of number; 

然后在存储过程中使用它们,就像

 PROCEDURE Your_Procedure_name( v_ret IN OUT SYS_REFCURSOR, i_idList integer_list, i_nameList string_list) IS begin -- Store passed object id list to array idList T_ID_TABLE := T_ID_TABLE(); ... begin -- Store passed object id list to array idList.Extend(i_idList.Count); FOR i in i_idList.first..i_idList.last loop idList(i) := i_idList(i); END LOOP; ... END Your_Procedure_name;