Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

C#:Berikan tipe yang ditentukan pengguna ke prosedur tersimpan Oracle

Berikut adalah pembantu yang saya gunakan untuk bekerja dengan prosedur tersimpan di Oracle:

internal class OracleDataHelper
{
    #region Variables
    private static readonly string _connectionString;
    #endregion

    #region Constructors
    static OracleDataHelper()
    {
        //_connectionString = ConfigurationManager.ConnectionStrings["..."]
        //    .ConnectionString;
    }
    #endregion

    public static object ExecuteScalar(string query)
    {
        object result;
        using (OracleConnection conn = new OracleConnection(ConnectionString))
        {
            conn.Open();
            OracleCommand command = new OracleCommand(query, conn);
            command.CommandType = CommandType.Text;

            result = command.ExecuteScalar();

            command.Dispose();
            conn.Close();
        }

        return result;
    }

    public static object ExecuteScalar(
        string query, 
        params object[] parameters)
    {
        object result;
        using (OracleConnection conn = new OracleConnection(ConnectionString))
        {
            conn.Open();
            OracleCommand command = new OracleCommand(query, conn);
            command.CommandType = CommandType.Text;
            command.Parameters.AddRange(
                ConvertParameters(parameters)
            );

            result = command.ExecuteScalar();

            command.Dispose();
            conn.Close();
        }

        return result;
    }

    public static int ExecuteNonQuery(string query)
    {
        return ExecuteNonQuery(query, new List<OracleParameter>());
    }

    public static int ExecuteNonQuery(
        string query, 
        List<OracleParameter> parameters)
    {
        int result = 0;

        using (OracleConnection conn = new OracleConnection(ConnectionString))
        {
            conn.Open();
            OracleCommand command = new OracleCommand(query, conn);
            command.CommandType = CommandType.Text;
            command.BindByName = true;
            command.Parameters.AddRange(
                ConvertParameters(parameters.ToArray())
            );

            result = command.ExecuteNonQuery();

            command.Dispose();
            conn.Close();
        }

        return result;
    }

    public static int ExecuteNonQuery(
        string query,
        params object[] parameters)
    {
        int result = 0;
        using (OracleConnection conn = new OracleConnection(ConnectionString))
        {
            conn.Open();
            OracleCommand command = new OracleCommand(query, conn);
            command.BindByName = true;
            command.CommandType = CommandType.Text;
            command.Parameters.AddRange(ConvertParameters(parameters));

            result = command.ExecuteNonQuery();

            command.Dispose();
            conn.Close();
        }

        return result;
    }

    public static OracleDataReader ExecuteReader(
        OracleConnection conn,
        string commandText
        )
    {
        OracleCommand command = new OracleCommand(commandText, conn);

        return command.ExecuteReader();
    }

    public static IDataReader ExecuteReader(
        OracleConnection conn, 
        string spName, 
        out List<OracleParameter> outParameters, 
        params object[] parameters)
    {
        throw new NotImplementedException();
    }

    public static int ExecuteProcedure(
        string spName,
        out OutputParameters outputParameters,
        params object[] parameters)
    {
        int result = 0;

        using (OracleConnection conn = new OracleConnection(ConnectionString))
        {
            conn.Open();
            OracleCommand command = new OracleCommand(spName, conn);
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.AddRange(ConvertParameters(parameters));

            result = command.ExecuteNonQuery();
            outputParameters = GetOutputParameters(command.Parameters);

            command.Dispose();
            conn.Close();
        }

        return result;
    }

    public static int ExecuteProcedure(
        string spName,
        params object[] parameters)
    {
        int result = 0;

        using (OracleConnection conn = new OracleConnection(ConnectionString))
        {
            conn.Open();
            OracleCommand command = new OracleCommand(spName, conn);
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.AddRange(ConvertParameters(parameters));

            result = command.ExecuteNonQuery();

            command.Dispose();
            conn.Close();
        }

        return result;
    }

    public static OracleDataReader ExecuteProcedure(
        OracleConnection conn,
        string spName,
        out OutputParameters outputParameters,
        params object[] parameters
        )
    {
        OracleCommand command = new OracleCommand(spName, conn);
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.AddRange(ConvertParameters(parameters));

        OracleDataReader reader = command.ExecuteReader();
        outputParameters = GetOutputParameters(command.Parameters);
        command.Dispose();

        return reader;
    }

    public static OracleDataReader ExecuteProcedure(
        OracleConnection conn,
        string spName,
        params object[] parameters
        )
    {
        OracleCommand command = new OracleCommand(spName, conn);
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.AddRange(ConvertParameters(parameters));

        OracleDataReader reader = command.ExecuteReader();
        command.Dispose();

        return reader;
    }

    private static OracleParameter[] ConvertParameters(object[] parameters)
    {
        parameters = parameters ?? new object[] { };

        int parametersCount = parameters.Length;
        OracleParameter[] parametersArray = 
            new OracleParameter[parametersCount];

        for (int i = 0; i < parametersCount; i++)
        {
            object parameter = parameters[i];
            OracleParameter oracleParameter;

            if (parameter is OracleParameter)
            {
                oracleParameter = (OracleParameter)parameter;
                if (null == oracleParameter.Value)
                {
                    oracleParameter.Value = DBNull.Value;
                }
            }
            else
            {
                oracleParameter = new OracleParameter();

                oracleParameter.Value = parameter == null ?
                    DBNull.Value :
                    parameter;
            }

            // adding udt mapping for the parameter
            if (oracleParameter.Value != null && 
                oracleParameter.Value is IOracleCustomTypeFactory)
            {
                MemberInfo info = oracleParameter.Value.GetType();
                OracleCustomTypeMappingAttribute[] attributes =  
                        info.GetCustomAttributes(
                    typeof(OracleCustomTypeMappingAttribute), 
                        false
                    ) as OracleCustomTypeMappingAttribute[];
                if (null != attributes && attributes.Length > 0)
                {
                    oracleParameter.UdtTypeName = attributes[0].UdtTypeName;
                }
            }

            parametersArray[i] = oracleParameter;
        }

        return parametersArray;
    }

    private static OutputParameters GetOutputParameters(
        OracleParameterCollection parameters)
    {
        OutputParameters outputParameters = new OutputParameters();
        foreach (OracleParameter parameter in parameters)
        {
            if (parameter.Direction == ParameterDirection.Output)
                outputParameters.Add(parameter);
        }

        return outputParameters;
    }

    internal static string ConnectionString
    {
        get { return _connectionString; }
    }
}

Metode ini bekerja dengan UDT serta bekerja dengan parameter sederhana.

Berikut adalah contoh entitas UDT:

[Serializable]
[OracleCustomTypeMappingAttribute("MDSYS.SDO_GEOMETRY")]
public class SdoGeometry : IOracleCustomTypeFactory, 
                           IOracleCustomType, 
                           ICloneable, INullable
{
    #region Variables
    private int _sdoGType;
    private int _sdoSrid;
    private SdoPoint _sdoPoint;
    private SdoElemInfo _sdoElemInfo;
    private SdoOrdinates _sdoOrdinate;

    private bool _sdoGTypeIsNull;
    private bool _sdoSridIsNull;
    #endregion

    #region Properties
    [OracleObjectMappingAttribute("SDO_GTYPE")]
    public int SdoGType
    {
        get { return _sdoGType; }
        set
        {
            _sdoGType = value;
            _sdoGTypeIsNull = false;
        }
    }

    public SdoGeometryType SdoGeometryType
    {
        get { return (Entities.Geometry.SdoGeometryType)(SdoGType % 100); }
    }

    public int Dimensions
    {
        get { return (int)(SdoGType / 1000); }
    }

    public int LrsDimensions
    {
        get { return (int)((SdoGType / 100) % 10); }
    }

    [OracleObjectMappingAttribute("SDO_SRID")]
    public int SdoSrid
    {
        get { return _sdoSrid; }
        set
        {
            _sdoSrid = value;
            _sdoSridIsNull = false;
        }
    }

    [OracleObjectMappingAttribute("SDO_POINT")]
    public SdoPoint SdoPoint
    {
        get { return _sdoPoint; }
        set { _sdoPoint = value; }
    }

    [OracleObjectMappingAttribute("SDO_ELEM_INFO")]
    public SdoElemInfo SdoElemInfo
    {
        get { return _sdoElemInfo; }
        set { _sdoElemInfo = value; }
    }

    [OracleObjectMappingAttribute("SDO_ORDINATES")]
    public SdoOrdinates SdoOrdinates
    {
        get { return _sdoOrdinate; }
        set { _sdoOrdinate = value; }
    }

    public static SdoGeometry Null
    {
        get
        {
            SdoGeometry obj = new SdoGeometry();

            return obj;
        }
    }
    #endregion

    #region Constructors
    public SdoGeometry()
    {
        _sdoGTypeIsNull = true;
        _sdoSridIsNull = true;
        _sdoElemInfo = SdoElemInfo.Null;
        _sdoOrdinate = SdoOrdinates.Null;
        _sdoPoint = SdoPoint.Null;
    }

    public SdoGeometry(SdoGeometry obj)
    {
        if (obj != null && this != obj)
        {
            SdoGType = obj.SdoGType;
            SdoSrid = obj.SdoSrid;
            SdoPoint = (SdoPoint)obj.SdoPoint.Clone();
            SdoElemInfo = (SdoElemInfo)obj.SdoElemInfo.Clone();
            SdoOrdinates = (SdoOrdinates)obj.SdoOrdinates.Clone();
        }
    }

    public SdoGeometry(
        int gType,
        int srid,
        SdoPoint point,
        SdoElemInfo elemInfo,
        SdoOrdinates ordinate)
    {
        SdoGType = gType;
        SdoSrid = srid;
        SdoPoint = (SdoPoint)point.Clone();
        SdoElemInfo = (SdoElemInfo)elemInfo.Clone();
        SdoOrdinates = (SdoOrdinates)ordinate.Clone();
    }
    #endregion

    #region ICloneable Members
    public object Clone()
    {
        return new SdoGeometry(this);
    }
    #endregion

    #region IOracleCustomType Members
    public void FromCustomObject(OracleConnection con, IntPtr pUdt)
    {
        if (!_sdoGTypeIsNull)
            OracleUdt.SetValue(con, pUdt, "SDO_GTYPE", SdoGType);
        if (!SdoOrdinates.IsNull)
            OracleUdt.SetValue(con, pUdt, "SDO_ORDINATES", SdoOrdinates);
        if (!SdoElemInfo.IsNull)
            OracleUdt.SetValue(con, pUdt, "SDO_ELEM_INFO", SdoElemInfo);
        if (!_sdoSridIsNull)
            OracleUdt.SetValue(con, pUdt, "SDO_SRID", SdoSrid);
        else
            OracleUdt.SetValue(con, pUdt, "SDO_SRID", DBNull.Value);
        if (!SdoPoint.IsNull)
            OracleUdt.SetValue(con, pUdt, "SDO_POINT", SdoPoint);
    }

    public void ToCustomObject(OracleConnection con, IntPtr pUdt)
    {
        object sdoGType = OracleUdt.GetValue(con, pUdt, "SDO_GTYPE");
        _sdoGTypeIsNull = sdoGType == null || sdoGType is DBNull;
        if (!_sdoGTypeIsNull)
            SdoGType = (int)sdoGType;
        SdoOrdinates = 
            (SdoOrdinates)OracleUdt.GetValue(con, pUdt, "SDO_ORDINATES");
        SdoElemInfo = 
            (SdoElemInfo)OracleUdt.GetValue(con, pUdt, "SDO_ELEM_INFO");
        object sdoSrid = OracleUdt.GetValue(con, pUdt, "SDO_SRID");
        if (!(sdoSrid == null || sdoSrid is DBNull))
            SdoSrid = (int)sdoSrid;
        SdoPoint = (SdoPoint)OracleUdt.GetValue(con, pUdt, "SDO_POINT");
    }
    #endregion

    #region INullable Members
    public bool IsNull
    {
        get { return _sdoGTypeIsNull; }
    }
    #endregion

    #region IOracleCustomTypeFactory Members
    public IOracleCustomType CreateObject()
    {
        return new SdoGeometry();
    }
    #endregion
}

P.S. Selama proyek saya, Oracle merilis 3 versi ODP.NET. Hal yang menarik:kode yang bekerja untuk Oracle.DataAcess.dll versi 2.111.6.10 sama sekali tidak berfungsi untuk 2.111.6.20!

Tidak tahu versi ODP.NET mana yang sebenarnya sekarang tetapi contoh yang saya posting di atas berfungsi dengan baik dengan 2.111.6.10.

Semoga ini membantu. Semoga berhasil!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle SQL Where klausa untuk menemukan catatan tanggal yang lebih lama dari 30 hari

  2. MASUKKAN 10 juta kueri di bawah 10 menit di Oracle?

  3. Kesalahan saat Perbarui Gabung

  4. Oracle SQL plus bagaimana cara mengakhiri perintah dalam file SQL?

  5. Kesalahan SQL:ORA-02000:kata kunci SELALU hilang saat membuat tabel berbasis kolom identitas