sql >> データベース >  >> RDS >> Oracle

C#:ユーザー定義型をOracleストアドプロシージャに渡す

    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; }
        }
    }
    

    これらのメソッドは、UDTで機能するだけでなく、単純なパラメーターでも機能します。

    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.私のプロジェクト中に、OracleはODP.NETの3つのバージョンをリリースしました。興味深いことに、2.111.6.10バージョンのOracle.DataAcess.dllで機能したコードは、2.111.6.20ではまったく機能しませんでした。

    現在、ODP.NETのどのバージョンが実際に使用されているかはわかりませんが、上記で投稿したサンプルは2.111.6.10でうまく機能します。

    お役に立てれば。頑張ってください!



    1. Oracleデータベースが自動コミットに設定されているかどうかを確認するにはどうすればよいですか?

    2. MyBatisを使用してOracleで最後の挿入IDを取得するにはどうすればよいですか?

    3. GI12.2の変更

    4. MariaDBでのABS()のしくみ