Clase de conexión a Base de Datos Oracle con C# .NET

La gran mayoría de las aplicaciones de software requieren de conectarse a Bases de Datos y la mejor manera para ello, es hacerlo de forma estructurada y orientada a objetos, para lo cual construirse una clase que gestione estas labores resulta indispensable en cualquier programa que realicemos.

Otra ventaja de tener una clase de conexión a una Base de Datos, es la reutilización de la misma en tantos proyectos que emprendamos, de forma que dicha clase sera sólida y a prueba de fallos a causa de haber sido de sobra testada en otras aplicaciones.

En esta caso la conexión la realizaremos contra la Base de Datos Oracle y usando Oracle Data Provider for NET (ODP.NET), que nos permitirá trabajar con los datos de la DB.

Nótese es uso de Oracle.DataAccess.Client, que habremos agregado previamente como referencia del proyecto y que se obtiene de la instalación de Oracle data provider for Net (ODP.NET).

Este es el código de la clase para conectar a la DB de Oracle:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Data;
using System.Text;
using Oracle.DataAccess.Client;

/// <summary>
/// Clase de Conexión y empleo de la DB Oracle.
/// ODP.NET Oracle managed provider
/// </summary>
public class DBOracle : IDisposable
{

    // Variables.
    private OracleConnection ora_Connection;
    private OracleTransaction ora_Transaction;
    public OracleDataReader ora_DataReader;

    private struct stConnDB
    {
        public string CadenaConexion;
        public string ErrorDesc;
        public int ErrorNum;
    }
    private stConnDB info;

    // Indica el numero de intentos de conectar a la BD sin exito.
    public byte ora_intentos = 0;

    #region "Propiedades"

    /// <summary>
    /// Devuelve la descripcion de error de la clase.
    /// </summary>
    public string ErrDesc
    {
        get { return this.info.ErrorDesc; }
    }

    /// <summary>
    /// Devuelve el numero de error de la clase.
    /// </summary>
    public string ErrNum
    {
        get { return info.ErrorNum.ToString(); }
    }

    #endregion


    /// <summary>
    /// Constructor.
    /// </summary>
    public DBOracle(string Servidor, string Usuario, string Password)
    {
        // Creamos la cadena de conexión de la base de datos.
        info.CadenaConexion = string.Format("Data Source={0};User Id={1};Password={2};", Servidor, Usuario, Password);

        // Instanciamos objeto conecction.
        ora_Connection = new OracleConnection();

    }

    /// <summary>
    /// Implement IDisposable.
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Dispose de la clase.
    /// </summary>
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Liberamos objetos manejados.
        }

        try
        {
            // Liberamos los obtetos no manejados.
            if (ora_DataReader != null)
            {
                ora_DataReader.Close();
                ora_DataReader.Dispose();
            }

            // Cerramos la conexión a DB.
            if (!Desconectar())
            {
                // Grabamos Log de Error...
            }

        }
        catch (Exception ex)
        {
            // Asignamos error.
            AsignarError(ref ex);
        }

    }


    /// <summary>
    /// Destructor.
    /// </summary>
    ~DBOracle()
    {
        Dispose(false);
    }


    /// <summary>
    /// Se conecta a una base de datos de Oracle.
    /// </summary>
    /// <returns>True si se conecta bien.</returns>
    private bool Conectar()
    {

        bool ok = false;

        try
        {
            if (ora_Connection != null)
            {
                // Fijamos la cadena de conexión de la base de datos.
                ora_Connection.ConnectionString = info.CadenaConexion;
                ora_Connection.Open();
                ok = true;
            }
        }
        catch (Exception ex)
        {
            // Desconectamos y liberamos memoria.
            Desconectar();
            // Asignamos error.
            AsignarError(ref ex);
            // Asignamos error de función
            ok = false;            
        }

        return ok;

    }


    /// <summary>
    /// Cierra la conexión de BBDD.
    /// </summary>
    public bool Desconectar()
    {
        try
        {
            // Cerramos la conexion
            if (ora_Connection != null)
            {
                if (ora_Connection.State != ConnectionState.Closed)
                {
                    ora_Connection.Close();
                }
            }
            // Liberamos su memoria.
            ora_Connection.Dispose();
            return true;
        }
        catch (Exception ex)
        {
            AsignarError(ref ex);
            return false;
        }
    }


    /// <summary>
    /// Ejecuta un procedimiento almacenado de Oracle.
    /// </summary>
    /// <param name="oraCommand">Objeto Command con los datos del procedimiento.</param>
    /// <param name="SpName">Nombre del procedimiento almacenado.</param>
    /// <returns>True si el procedimiento se ejecuto bien.</returns>
    public bool EjecutaSP(ref OracleCommand OraCommand, string SpName)
    {

        bool ok = true;

        try
        {
            // Si no esta conectado, se conecta.
            if (!IsConected())
            {
                ok = Conectar();
            }

            if (ok)
            {
                OraCommand.Connection = ora_Connection;
                OraCommand.CommandText = SpName;
                OraCommand.CommandType = CommandType.StoredProcedure;
                OraCommand.ExecuteNonQuery();
            }
        }
        catch (Exception ex)
        {
            AsignarError(ref ex);
            ok = false;
        }

        return ok;

    }


    /// <summary>
    /// Ejecuta una sql que rellenar un DataReader (sentencia select).
    /// </summary>
    /// <param name="SqlQuery">sentencia sql a ejecutar</param>
    /// <returns></returns> 
    public bool EjecutaSQL(string SqlQuery)
    {

        bool ok = true;

        OracleCommand ora_Command = new OracleCommand();

        try
        {

            // Si no esta conectado, se conecta.
            if (!IsConected())
            {
                ok = Conectar();
            }

            if (ok)
            {
                // Cerramos cursores abiertos, para evitar el error ORA-1000
                if ((ora_DataReader != null))
                {
                    ora_DataReader.Close();
                    ora_DataReader.Dispose();
                }

                ora_Command.Connection = ora_Connection;
                ora_Command.CommandType = CommandType.Text;
                ora_Command.CommandText = SqlQuery;

                // Ejecutamos sql.
                ora_DataReader = ora_Command.ExecuteReader();
            }

        }
        catch (Exception ex)
        {
            AsignarError(ref ex);
            ok = false;
        }
        finally
        {
            if (ora_Command != null)
            {
                ora_Command.Dispose();
            }
        }

        return ok;

    }



    /// <summary>
    /// Ejecuta una sql que no devuelve datos (update, delete, insert).
    /// </summary>
    /// <param name="SqlQuery">sentencia sql a ejecutar</param>
    /// <param name="FilasAfectadas">Fila afectadas por la sentencia SQL</param>
    /// <returns></returns>
    public bool EjecutaSQL(string SqlQuery, ref int FilasAfectadas)
    {

        bool ok = true;
        OracleCommand ora_Command = new OracleCommand();

        try
        {

            // Si no esta conectado, se conecta.
            if (!IsConected())
            {
                ok = Conectar();
            }

            if (ok)
            {
                ora_Transaction = ora_Connection.BeginTransaction();
                ora_Command = ora_Connection.CreateCommand();
                ora_Command.CommandType = CommandType.Text;
                ora_Command.CommandText = SqlQuery;
                FilasAfectadas = ora_Command.ExecuteNonQuery();
                ora_Transaction.Commit();
            }

        }
        catch (Exception ex)
        {
            // Hacemos rollback.
            ora_Transaction.Rollback();
            AsignarError(ref ex);
            ok = false;
        }
        finally
        {
            // Recolectamos objetos para liberar su memoria.
            if (ora_Command != null)
            {
                ora_Command.Dispose();
            }
        }

        return ok;

    }


    /// <summary>
    /// Captura Excepciones
    /// </summary>
    /// <param name="ex">Excepcion producida.</param>
    private void AsignarError(ref Exception ex)
    {
        // Si es una excepcion de Oracle.
        if (ex is OracleException)
        {
            info.ErrorNum = ((OracleException)ex).Number;
            info.ErrorDesc = ex.Message;
        }
        else
        {
            info.ErrorNum = 0;
            info.ErrorDesc = ex.Message;
        }
        // Grabamos Log de Error...
    }



    /// <summary>
    /// Devuelve el estado de la base de datos
    /// </summary>
    /// <returns>True si esta conectada.</returns>
    public bool IsConected()
    {

        bool ok = false;

        try
        {
            // Si el objeto conexion ha sido instanciado
            if (ora_Connection != null)
            {
                // Segun el estado de la Base de Datos.
                switch (ora_Connection.State)
                {
                    case ConnectionState.Closed:
                    case ConnectionState.Broken:
                    case ConnectionState.Connecting:
                        ok = false;
                        break;
                    case ConnectionState.Open:
                    case ConnectionState.Fetching:
                    case ConnectionState.Executing:
                        ok = true;
                        break;
                }
            }
            else
            {
                ok = false;
            }

        }
        catch (Exception ex)
        {
            AsignarError(ref ex);
            ok = false;
        }

        return ok;

    }

}

Para usar la clase hay que llamar al constructor de la misma pasándole los parámetros de conexión.

Ejecutar consultas resulta simple llamando a la función EjecutaSQL, la cual según los parámetros que reciba ejecutara sentencias de tipo SELECT o de tipo UPDATE, DELETE,

Para recuperar un conjunto de datos, usariamos:

        DBOracle DB = new DBOracle("Servidor", "Usuario", "Password");
        string sql = "SELECT nombre FROM usuarios";

        try
        {
            if (DB.EjecutaSQL(sql))
            {
                while (DB.ora_DataReader.Read())
                {
                    string resultado = DB.ora_DataReader["nombre"];
                }
            }
        }
        catch (Exception ex)
        {
            // Gestion de errores.
        }
        finally
        {
            DB.Dispose();
        }

Y para consultas tipo INSERT, UPDATE y DELETE:

int filas = 0;
DBOracle DB = new DBOracle("Servidor", "Usuario", "Password");
bool ok = DB.EjecutaSQL("DELETE FROM usuarios WHERE id_usuario = 4", filas);
DB.Disponse();

De esta manera en caso de error, tendríamos la variable ok a false y en caso contrario en la variable filas tendriamos el número de registros afectados. Hay que tener en cuenta que este número puede ser cero y eso no representa un error per se.

 

38114 visitas.

12 comentarios sobre “Clase de conexión a Base de Datos Oracle con C# .NET

  1. Amigo me puedes enviar el código fuente tu clase y tu forma de implementarlo me parece interesante….. gracias antemano y chvr esta tu paguina sigue adelante

  2. Saludos Amigo

    Me podrias enviar el codigo fuente y la clase y tu forma de implementar. esta muy interesante

    Yo necesito crear un conector tanto para Oracle, Sqlserver y Sybase y he visto el script que publicaste y me parece muy interesante.

    Gracias de antemano.

     

  3. Si fueras tan amable de enviarme la case y la forma de utilizar el codigo te lo agradeceria

     

  4. Hola,

    En el artículo tenéis la clase entera, copiarla y meterla como clase en vuestro proyecto.

    El artículo también explica al final como usarla.

    Un saludo.

  5. Hola,

    es justo la parte de mi Trabajo fin de Grado que necesitaba para interactuar con una BD Oracle. Si no te importa voy a utilizar tu clase que me va ahorrar un tiempo precioso. Por supuesto haré una referencia al sitio.

    Muchas gracias por la aportación.

    Un abrazo.

     

  6. Hola amigo, Disculpa la pregunta tal vez es bastante sencilla pero me gustaria saber como hago si quiero llamar un procedimiento que de la BD

     

    Gracias

  7. Gracias por el aporte, pero si me podrías facilitar el código fuente y la forma en que lo empleas, gracias de antemano

    • Ya lo he dicho comentarios atrás, el código fuente y la forma de utilizarlo es exactamente lo que viene en este artículo… copiar el código de la clase y lo metéis en vuestro proyecto y lo utilizáis como se dice abajo en el post.

  8. Que tal Amigo
    Agrdezco tu aportacion con este metodo, que me sera de utilidad, solo tengo una duda me esta mandando un mensaje en la siguiente linea
    info.ErrorNum = ((OracleException)ex).Number; <—- AQUI ME DIRE QUE NO SE ENCUENTRA NINGUN METODO .Number
    Que me estara faltando por hacer?
    Ya cargue la referencia Oracle .Net.

    Saludos.

    • Hola Lench,
      Pues es raro, si ya has cargado la librería de Oracle.DataAccess.Client y la instancias al principio debería funcionar. En todo caso, al ser una línea de información del número de error, puedes comentarla sin problema para ver si el resto te funciona sin problemas.
      Saludos.

Comentarios cerrados.