OracleParameter.ArrayBindSize,这里集合元素是变长的VARCHAR2,因此需要为每个元素指定其长度,由于表中last_name的长度是25,所以这里定义成了25,比25小不会报错,但是可能导致字符串被截断。如果要返回的集合元素是NUMBER,则可以不指定ArrayBindSize,
OracleString,不要天真地以为可以使用string[]数组来接收返回的集合,NO!需要OracleString[],使用string[]将导致转化出错。如果要返回的集合元素是NUMBER,通常用OracleDecimal[]而不能直接用decimal[]。
通常来说,以集合类型作为输出参数类型的情况相对较少,对于结果集,使用REF Cursor是更好的选择。
3.嵌套表(Nested table)
对于Nested table,有两种方案可以选择,1)直接映射成C#中的数组,2)映射成C#的自定义类型。
第一种方案,需要首先声明一个Factory类并实现IOracleArrayTypeFactory接口,并使用OracleCustomTypeMappingAttribute(schema.type_name)指定需要映射的Nested table的名称,schema.type_name需要大写。
可以看到我们使用了OracleDbType.Array,并且指定了参数的UdtTypeName。赋值时直接使用了string[]。
[OracleCustomTypeMappingAttribute("HR.T_NESTED_TAB_STR")]
public class Nested_Tab_Mapping_To_Array_Factory : IOracleArrayTypeFactory
{
public Array CreateArray(int i)
{
return new string[i];
}
//
public Array CreateStatusArray(int i)
{
return new OracleUdtStatus[i];
}
}
(作为输入参数)
cmd.CommandText = "pkg_odp_dotnet.proc_nested_tab_str_in";
cmd.CommandType = CommandType.StoredProcedure;
//
OracleParameter op = new OracleParameter();
op.ParameterName = "p_nested_tab_str";
op.Direction = ParameterDirection.Input;
op.OracleDbType = OracleDbType.Array;
op.UdtTypeName = "HR.T_NESTED_TAB_STR";
op.Value = new string[] { "King", "Olsen" };
//
cmd.Parameters.Add(op);
cmd.ExecuteNonQuery();
(作为输出参数,同样需要上面的Factory类)
cmd.CommandText = "pkg_odp_dotnet.proc_nested_tab_str_out";
cmd.CommandType = CommandType.StoredProcedure;
//
OracleParameter op = new OracleParameter();
op.ParameterName = "p_nested_tab_str";
op.Direction = ParameterDirection.Output;
op.OracleDbType = OracleDbType.Array;
op.UdtTypeName = "HR.T_NESTED_TAB_STR";
//
cmd.Parameters.Add(op);
cmd.ExecuteNonQuery();
//
if (op.Value != DBNull.Value)
{
string[] result = (string[])op.Value;
foreach (string s in result)
{
Console.WriteLine(s);
}
}
对比而言,第一种方案中将Nested table映射成C#数组的做法更简洁。下面我们介绍第二种方案,稍微繁杂一点,除了需要Factory类(需要同时实现IOracleArrayTypeFactory与IOracleCustomTypeFactory两个接口)外,它还需要一个自定义类型:
[OracleCustomTypeMappingAttribute("HR.T_NESTED_TAB_STR")]
public class Nested_Tab_Mapping_To_Object_Factory : IOracleCustomTypeFactory, IOracleArrayTypeFactory
{
public IOracleCustomType CreateObject()
{
return new Nested_Tab_Mapping_To_Object();
}
//
public Array CreateArray(int i)
{
return new String[i];
}
//
public Array CreateStatusArray(int i)
{
return new OracleUdtStatus[i];
}
}
public class Nested_Tab_Mapping_To_Object : IOracleCustomType, INullable
{
[OracleArrayMapping()]
public string[] container;
//
private OracleUdtStatus[] statusArray;
public OracleUdtStatus[] StatusArray
{
get
{
return statusArray;
}
set
{
statusArray = value;
}
}
//
private bool isNull;
public bool IsNull
{
get
{
return isNull;
}
}
//
public static Nested_Tab_Mapping_To_Object Null
{
get
{
Nested_Tab_Mapping_To_Object nt = new Nested_Tab_Mapping_To_Object();
nt.isNull = true;
return nt;
}
}
//
public void ToCu