0

创建一个包来定义一个自定义集合和一个将此自定义集合作为输入参数的存储过程。如何从 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\" 未找到"

4

1 回答 1

1

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

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

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

于 2013-03-15T03:00:21.800 回答