Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

C #:Chuyển một kiểu do người dùng xác định vào một thủ tục được lưu trữ Oracle

Đây là một trình trợ giúp mà tôi đã sử dụng để làm việc với các thủ tục được lưu trữ trong 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; }
    }
}

Các phương thức này hoạt động với UDT cũng như chúng hoạt động với các tham số đơn giản.

Đây là một ví dụ về thực thể 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. Trong dự án của tôi, Oracle đã phát hành 3 phiên bản ODP.NET. Điều thú vị:mã hoạt động cho phiên bản 2.111.6.10 của Oracle.DataAcess.dll hoàn toàn không hoạt động cho 2.111.6.20!

Không biết phiên bản ODP.NET nào là thực tế bây giờ nhưng các mẫu tôi đã đăng ở trên hoạt động tốt với 2.111.6.10.

Hi vọng điêu nay co ich. Chúc bạn thành công!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách chạy tập lệnh SQL Plus trong PowerShell

  2. Tách chuỗi được phân tách bằng dấu phẩy trong một chương trình được lưu trữ PL / SQL

  3. Oracle:Làm thế nào để nhóm theo một phạm vi?

  4. ORA-00907:thiếu dấu ngoặc đơn bên phải

  5. Làm cách nào để khắc phục lỗi này:SQL92 không được hỗ trợ?