在 c# 中,我尝试调用一个存储过程,该过程将已定义类型的实例作为输入。
架构定义类型如下所示:
CREATE TYPE TEST.TBL_IDS IS TABLE OF VARCHAR2(64)
存储过程定义:
PROCEDURE TEST_PACKAGE.TEST_PROC(inIDs IN TEST.TBL_IDS);
我在 c# 中的代码如下:
用于映射 Oracle 数据类型 + 所需工厂的类
public class TBL_IDS : INullable, IOracleCustomType
{
[OracleArrayMapping()]
public string[] IDs;
private bool objectIsNull;
#region INullable Members
public bool IsNull
{
get { return objectIsNull; }
}
public static TBL_IDS Null
{
get
{
TBL_IDS obj = new TBL_IDS();
obj.objectIsNull = true;
return obj;
}
}
#endregion
//must implement these for IOracleCustomType interface
#region IOracleCustomType Members
public void FromCustomObject(OracleConnection con, IntPtr pUdt)
{
OracleUdt.SetValue(con, pUdt, 0, IDs);
}
//
public void ToCustomObject(OracleConnection con, IntPtr pUdt)
{
IDs = (string[])OracleUdt.GetValue(con, pUdt, 0);
}
#endregion
}
[OracleCustomTypeMapping("TEST.TBL_IDS")]
public class IDsFactory : IOracleCustomTypeFactory, IOracleArrayTypeFactory
{
#region IOracleCustomTypeFactory Members
public IOracleCustomType CreateObject()
{
return new TBL_IDS();
}
#endregion
#region IOracleArrayTypeFactory Members
public Array CreateArray(int numElems)
{
return new TBL_IDS[numElems];
}
public Array CreateStatusArray(int numElems)
{
return null;
}
#endregion
}
参数的实际绑定:
string[] ids = { "Item1", "Item2", "Item3", "Item4" };
TBL_IDS tblIDs = new TBL_IDS();
OracleParameter parameter = new OracleParameter();
parameter.ParameterName = "inIDs";
parameter.OracleDbType = OracleDbType.Array;
parameter.Direction = ParameterDirection.Input;
parameter.UdtTypeName = "TEST.TBL_IDS";
parameter.Value = tblIDs;
代码成功编译并运行,但实际上并未将数组发送到存储过程。我看过这个类似的问题,但给出的答案不起作用(其他发表评论的人似乎也是如此(。
现在让它工作了。问题是由于我的代码将嵌套表视为自定义类型的表而不是varchar2(64)
表。
只需要将映射更改为以下内容(请注意,我删除了class TBL_IDS
,因为它不需要(:
[OracleCustomTypeMapping("TEST.TBL_IDS")]
public class TBL_IDS_FACTORY : IOracleArrayTypeFactory
{
#region IOracleArrayTypeFactory Members
public Array CreateArray(int numElems)
{
return new string[numElems];
}
public Array CreateStatusArray(int numElems)
{
return null;
}
#endregion
}
c# 中的实际绑定(只需绑定字符串数组而不是自定义对象(:
string[] ids = { "Item1", "Item2", "Item3", "Item4" };
OracleParameter parameter = new OracleParameter();
parameter.ParameterName = "inIDs";
parameter.OracleDbType = OracleDbType.Array;
parameter.Direction = ParameterDirection.Input;
parameter.UdtTypeName = "TEST.TBL_IDS";
parameter.Value = ids ;
希望这可以帮助任何有我同样问题的人。