【问题标题】:Pass UDT defined in a package as a parameter to stored proc in Oracle将包中定义的 UDT 作为参数传递给 Oracle 中的存储过程
【发布时间】:2013-03-14 21:34:53
【问题描述】:

创建一个包来定义一个自定义集合和一个以该自定义集合作为输入参数的存储过程。如何从 c# 调用这个过程?

这是包裹:

CREATE OR REPLACE PACKAGE pkg_name
AS
    TYPE customCollectionType IS VARRAY(200) OF VARCHAR2 (1000);

    PROCEDURE ProcName(p_collection IN customCollectionType);
END pkg_name;
/
CREATE OR REPLACE PACKAGE BODY pkg_name
AS
    PROCEDURE StudyProc (p_StudyNum   IN     customCollectionType)
    IS
    ........................
END pkg_name;

这里是 customCollectionType 的工厂实现:

public class PlaceHolderType : IOracleCustomType, INullable
{
    [OracleArrayMapping()]
    public string[] Array;
    private bool m_bIsNull;
    private OracleUdtStatus[] m_statusArray;

    public OracleUdtStatus[] StatusArray
    {
        get
        {
            return this.m_statusArray;
        }
        set
        {
            this.m_statusArray = value;
        }
    }

    public virtual bool IsNull
    {
        get
        {
            return m_bIsNull;
        }
    }

    public static PlaceHolderType Null
    {
        get
        {
            PlaceHolderType p = new PlaceHolderType();
            p.m_bIsNull = true;
            return p;
        }
    }

    public virtual void FromCustomObject(OracleConnection con, IntPtr pUdt)
    {
        OracleUdt.SetValue(con, pUdt, 0, Array, m_statusArray);
        return;
    }

    public virtual void ToCustomObject(OracleConnection con, IntPtr pUdt)
    {
        object objectStatusArray = null;
        Array = (string[])OracleUdt.GetValue(con, pUdt, 0, out objectStatusArray);
        m_statusArray = (OracleUdtStatus[])objectStatusArray;
    }

    public override string ToString()
    {
        return string.Empty;
    }
}

[OracleCustomTypeMappingAttribute("USER_NAME.PKG_NAME.CUSTOMCOLLECTIONTYPE")]
public class CUSTOMCOLLECTIONTYPE: IOracleCustomTypeFactory, IOracleArrayTypeFactory
{
    // Implementation of IOracleCustomTypeFactory.CreateObject()
    public IOracleCustomType CreateObject()
    {
        // Return a new custom object
        //OracleString or;
        return new PlaceHolderType();
    }

    #region IOracleArrayTypeFactory Members
    public Array CreateArray(int numElems)
    {
        return new string[numElems];
    }

    public Array CreateStatusArray(int numElems)
    {
        return new OracleUdtStatus[numElems];
    }

    #endregion
}

来电:

cmd.Connection = OracleConnectionObj;
cmd.BindByName = true;
cmd.CommandText = "PKG_NAME.PROC_NAME";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
OracleParameter param1 = new OracleParameter();
Array inputValue = (new CUSTOMCOLLECTIONTYPE()).CreateArray(5);
System.Array.Copy(SomeArray, inputValue, 5);
param1.OracleDbType = OracleDbType.Array;
param1.Direction = ParameterDirection.Input;
param1.UdtTypeName = "USER_NAME.CUSTOMCOLLECTIONTYPE";
param1.Value = inputValue;
cmd.Parameters.Add(param1);
cmd.ExecuteNonQuery();

.Net 中的错误是:

“OCI-22303:类型 \"USER_NAME\"。\"CUSTOMCOLLECTIONTYPE\" 未找到”

【问题讨论】:

    标签: oracle parameter-passing user-defined-types custom-collection


    【解决方案1】:

    当您从 C# 将对象传递给映射到 UDT 的过程时,您需要在架构级别而不是包级别定义类型。因此,您需要在 sqlplus 中执行以下命令:-

    Create Type customCollectionType AS VARRAY(200) OF VARCHAR2 (1000);
    

    并从您的包规范中删除 customCollectionType 的声明。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2023-03-22
    • 2017-12-24
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多