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

时间:2018-02-01 18:33:11

标签: c# sql .net oracle odp.net

In c#, I am trying to call a stored procedure that takes as input an instance of a defined type.

Schema defined type as follows:

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

Stored procedure definition:

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

My code in c# is as follows:

Class to map the Oracle data type + the required factory

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
}

The actual binding of the parameter:

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;

The code compiles and runs successfully, but is not actually sending the array to the stored procedure. I've looked at this similar question but the answer given does not work (which appears to be the case for other people who commented as well).

1 个答案:

答案 0 :(得分:1)

现在就开始工作了。问题是由于我的代码将嵌套表视为自定义类型的表而不是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 ;

希望这有助于任何遇到同样问题的人。