.NET Oracle UDT 参数绑定(架构定义嵌套 table)

.NET Oracle UDT Parameter Binding (schema defined nested table)

在 c# 中,我试图调用一个存储过程,该过程将定义类型的实例作为输入。

架构定义类型如下:

CREATE TYPE TEST.TBL_IDS IS TABLE OF VARCHAR2(64)

存储过程定义:

PROCEDURE TEST_PACKAGE.TEST_PROC(inIDs IN TEST.TBL_IDS);

我的c#代码如下:

Class映射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;

代码编译并成功运行,但实际上并未将数组发送到存储过程。我看过这个 similar question 但给出的答案不起作用(其他发表评论的人似乎也是如此)。

现在可以使用了。问题是由于我的代码将嵌套 table 视为自定义类型的 table 而不是 varchar2(64).

的 table

只需要将映射更改为以下内容(请注意,我删除了 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 ;

希望这可以帮助遇到同样问题的人。