【问题标题】:.NET Oracle UDT Parameter Binding (schema defined nested table).NET Oracle UDT 参数绑定(架构定义的嵌套表)
【发布时间】:2018-02-01 18:33:11
【问题描述】:

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

Schema定义类型如下:

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;

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

【问题讨论】:

  • 我注意到您正在手动编码 TBL_IDS 类,这很好。但是,我想我会向其他人指出,作为 Visual Studio 的 Oracle 开发人员工具的一部分,有一个代码生成向导可以帮助自动设置所需的类。这是一个教程:apexapps.oracle.com/pls/apex/…

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


【解决方案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 ;

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

【讨论】:

  • 而且由于您没有使用 UDT,因此也不需要“parameter.UdtTypeName”行。
猜你喜欢
  • 2011-05-15
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2012-06-29
相关资源
最近更新 更多