我有一个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();
我的所有程序都记录了一条消息。我只是想让这个概念起作用。
答案 0 :(得分:5)
你可以从(更简单的方式)开始:
List<int> idList = yourObjectList;
List<int> 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:
中添加包/过程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;