none
Ayuda Oracle ODAC conexion RRS feed

  • Pregunta

  • Hola, estoy usando Oracle ODAC para realizar transacciones desde C#, y me gustaría que alguien me ayudara ya que tengo un problema. Cuando realizó inserts todo funciona de maravilla, pero realizó updates y deletes y NO me funcionan, se me queda pegado el programa. Alguien sabe que puede ser?

    este es un poco del código:

    public bool Modificar()
            {
                try
                {
    
                    ObjetoEnBD.queryString = "update Actor set codigo = '" + this.codigo + "', nombre = '" + this.nombre + "' where codigo = '" + this.codigo + "'";
                    ObjetoEnBD.command.CommandText = queryString;
                    ObjetoEnBD.command.Connection = cnx;
                    ObjetoEnBD.command.ExecuteNonQuery();
    
                    return true;
                }
                catch
                {
                    throw;
                }
                return false;
            }

    se deben enviar dos parámetros, a la base.

    Muchas Gracias!

    martes, 8 de octubre de 2013 22:06

Respuestas

  • Bueno Sergio después de horas y horas de largo análisis, al fin lo logré. Creo que es justo colocar la respuesta o el método final:

    public bool Modificar()
            {
                
                try
                {
                    ObjetoEnBD.command = ObjetoEnBD.cnx.CreateCommand();
                    ObjetoEnBD.transaction = ObjetoEnBD.cnx.BeginTransaction(IsolationLevel.ReadCommitted);
                    ObjetoEnBD.command.Transaction = ObjetoEnBD.transaction;
    
                    command.CommandText = "UPDATE ACTOR SET NOMBRE = '" + this.nombre + "' WHERE CODIGO = '" + this.codigo + "'";
                    command.ExecuteNonQuery();
    
                    ObjetoEnBD.transaction.Commit();
    
                    return true;
                }
                catch
                {
                    return false;
                }
            }

    Se que debo colocar los parámetros por separado, y no colocarlo todo en el string, como bien explicabas tu y Tuttini pero hasta la fecha queda listo, voy a empezar a implementar los parámetros por separado.

    Muchas Gracias, Pura Vida.

    • Marcado como respuesta Kent-15 jueves, 10 de octubre de 2013 16:35
    jueves, 10 de octubre de 2013 4:29

Todas las respuestas

  • Hola amigo, si estas abriendo la conexión a la base de datos, ya que no veo que lo estés haciendo antes de ejecutar el query, cnx es una conexión que esta abierta esta seguro? recuerda que debes hacerl cnx.open()

    espero te sirva, saludos.


    El Tavo http://eltavodev.blogspot.com/

    martes, 8 de octubre de 2013 22:53
  • Hola Tavo, de hecho me pidieron que abriera la conexión antes, en el main. Aunque no es nada recomendado, pero de hecho desde ahí la abro y luego llamo todos los métodos como insert, update y deldete.

    Lo que pasa es que estos elementos están en una clase distinta y son declarados como staticos.

     public static OracleConnection cnx;
     public static OracleCommand command;
     public static string queryString;
     public static OracleTransaction txn;
    No tengo idea porque se me queda pegada la base, es raro porque con los inserts no me genera ningún problema.

    martes, 8 de octubre de 2013 23:01
  • Yo primero decirte que uses consultas parametrizadas siempre, eso son buenas practicas de programación y no la concatenación de los valores. Además crea la conexión y usala en el mismo método ya que así controlas que siempre este cerrada.

    public bool Modificar() { try { using(OracleConnection cnx = new OracleConnection(cadenaConexion) { ObjetoEnBD.queryString = "update Actor set codigo = :codigo, nombre = :nombre where codigo = :codigo"; ObjetoEnBD.command.CommandText = queryString; ObjetoEnBD.command.Parameters.AddWithValue(":código", thid.codigo); ObjetoEnBD.command.Parameters.AddWithValue (":nombre", thid.nombre); ObjetoEnBD.command.Connection = cnx; ObjetoEnBD.command.ExecuteNonQuery();

    cnx.Close();

    cnx.Dispose();

    return true; } } catch { cnx.Close();

    throw; } return false; }


    en el bloque using garantizas el cierre de la conexion

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    • Propuesto como respuesta Pedro Ávila miércoles, 9 de octubre de 2013 14:41
    martes, 8 de octubre de 2013 23:03
    Moderador
  • Kent y que error te saca? de que tipo es tu campo codigo por que si es numeric o int no puedes ponerle comilla simple.

    Saludos.


    El Tavo http://eltavodev.blogspot.com/

    martes, 8 de octubre de 2013 23:27
  • estoy usando Oracle ODAC para realizar transacciones desde C#

    noooo, como odbc eso nunca una pesima idea

     

    Build a .NET Application on the Oracle Database with Visual Studio 2005 or 2008

    tienes que descargar el ODAC y referenciar la libreria de este para ADO.NET, pero nucna uses odbc

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    martes, 8 de octubre de 2013 23:41
  • No me saca ningún error, solo se me queda pegado. O sea cuando hace el execute se queda ahí, los dos campos son de tipo varchar2.
    miércoles, 9 de octubre de 2013 7:35
  • No use el odbc, lo que puse era para aclarar que estaba usando conexión ODAC, siempre me a funcionado muy bien, pero parece que esta vez de forma estática me esta generando problemas.
    miércoles, 9 de octubre de 2013 7:37
  • lo que puse era para aclarar que estaba usando conexión ODAC

    ahh era ODAC no se porque lei que decia odbc, entonces esta correcto

    pero parece que esta vez de forma estática me esta generando problemas.

    lo que recomendaria es que uses parametros en la query

    concatener los valores en un string no es correcto

    http://social.msdn.microsoft.com/Forums/es-ES/55061187-d5ca-4d01-b5f6-6b6c9bd7ab86/como-crear-un-login-con-c-y-conectado-oracle?forum=vcses

    http://social.msdn.microsoft.com/Forums/es-ES/a80fb8fa-ead9-4aab-843d-f17fe32b20bd/conectar-c-windos-form-con-la-bd-oracle?forum=vcses

    analiza los ejemplos de los links, veras que se definemediante ":" los parametros y se asigna el valor en OracleCommand.Parameters

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 9 de octubre de 2013 10:14
  • Hola Kent, puedes por favor mostrar el código que usas para el insert que si te funciona? para poder ayudarte.

    Saludos.


    El Tavo http://eltavodev.blogspot.com/

    miércoles, 9 de octubre de 2013 18:44
  • Si, muchas gracias por tu ayuda. Este es el código:

    Usado en el método

    ObjetoEnBD.queryString = "UPDATE ACTOR SET NOMBRE = '" + this.nombre + "' WHERE CODIGO = '" + this.codigo + "'";
    Usado directamente en la base
    UPDATE ACTOR SET NOMBRE = 'nuevo_nombre' WHERE CODIGO = '12A3B';

    Muchas gracias.

    miércoles, 9 de octubre de 2013 18:55
  • recuerda usar parametros

    mientras concatenes en un string siempre tendras problemas

    Nota: analiza lo que comente y tambien Sergio sobre los parametros

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 9 de octubre de 2013 19:24
  • Aquí un ejemplo de como lo hago yo con Oracle:

    public static void UpStProcess(csRqDAWs cs)
            {
                using(OracleConnection cnn = new OracleConnection(Conn.Orast))
                {
                    const string sql = @"insert into logssUser(idlog, usuario, status, fecha, ejercicio, consecutivo, proceso, pcname, pcuser, nuevono)
                    values (s_logsstatus.nextval, :u, :st, sysdate, :e, :c, :p, :pn, :pu, :nn)";
                    using(OracleCommand cmd = new OracleCommand(sql, cnn))
                    {
                        cmd.Parameters.Add(":u", OracleDbType.Char).Value = cs.Usuario;
                        cmd.Parameters.Add(":st", cs.ReqStatus);
                        cmd.Parameters.Add(":e", cs.Ejercicio);
                        cmd.Parameters.Add(":c", cs.Consecutivo);
                        cmd.Parameters.Add(":p", cs.Process);
                        cmd.Parameters.Add(":pn", cs.PCName);
                        cmd.Parameters.Add(":pu", cs.PCUserName);
                        cmd.Parameters.Add(":nn", cs.NuevoNo);
                        cnn.Open();
                        cmd.ExecuteNonQuery();
                    }
                }
            }

    Saludos!


    Comparto y aprendo. Saludos desde África

    miércoles, 9 de octubre de 2013 20:05
  • Si, muchas gracias Tuttini. Utilicé los parámetros de forma correcta y el resultado fue el mismo, en este caso volví a colocar el código porque el método parametrizado se encuentra comentado. Pero sinceramente no me ha dado ningún problema, estaba viendo un método transaction() en la conexion que me gustaría probar, pero se ve algo complicado. Sabes algo sobre eso?
    miércoles, 9 de octubre de 2013 20:43
  • Utilicé los parámetros de forma correcta y el resultado fue el mismo

    podrias poner el codigo que generaste utilizando parametros ?

    porque me suena muy raro que usando parametros tengas el mismo resultado

    recuerda mencionar que mensaje de error recibes


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 9 de octubre de 2013 20:49
  • Es que no recibo errores Leandro, todo se compila de maravilla, funciona perfecto, lo que pasa es que lo he debugueado detenidamente y cuando realizo el execute final se me queda pegado y luego no me pasa.

    Algo que debo mencionarte nuevamente es que SIEMPRE me funciona al realizar inserts, no me da ningún error en esos caso, aún usando concatenación para el query, me funciona bien. Los únicos casos que se me queda pegado son update y delete.

    miércoles, 9 de octubre de 2013 21:04
  • Has verificado que en tu tabla tenga un índice por el campo código?lo digo porque si no tiene, a la hora de actualizar o borrar un registro el motor debe recorrerse la tabla entera hasta que lo encuentra

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    miércoles, 9 de octubre de 2013 21:09
    Moderador
  • Hola Sergio, un cordial saludo. Fijate que la base es demasiado sencilla porque es lo menos que se quiere medir con mi prueba, hechale un vistaso:

    CREATE TABLE Actor
    (
    	CODIGO VARCHAR(4) not null,
    	NOMBRE VARCHAR(100) not null
    )
    GO
    
    
    CREATE TABLE Video
    (
    	CODIGO VARCHAR(4) not null,
    	TITULO VARCHAR(100) not null
    )
    GO
    
    
    CREATE TABLE Protagonistas
    (
    	VIDEO VARCHAR(4) not null,
    	ACTOR VARCHAR(4) not null
    )
    GO

    Mira que la consulta manualmente me funciona muy bien.



    • Editado Kent-15 miércoles, 9 de octubre de 2013 21:23
    miércoles, 9 de octubre de 2013 21:21
  • Si no te digo que no te funcione bien, solo digo que hagas la prueba de crear un indice por ese campo. Ahora con pocos registros puede ir bien pero cuando tengas cientos de miles o millones ya veras como tarda. Haz dicha prueba y comenta.si no es eso buscamos otra solucion 

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    miércoles, 9 de octubre de 2013 21:28
    Moderador
  • Bueno Sergio después de horas y horas de largo análisis, al fin lo logré. Creo que es justo colocar la respuesta o el método final:

    public bool Modificar()
            {
                
                try
                {
                    ObjetoEnBD.command = ObjetoEnBD.cnx.CreateCommand();
                    ObjetoEnBD.transaction = ObjetoEnBD.cnx.BeginTransaction(IsolationLevel.ReadCommitted);
                    ObjetoEnBD.command.Transaction = ObjetoEnBD.transaction;
    
                    command.CommandText = "UPDATE ACTOR SET NOMBRE = '" + this.nombre + "' WHERE CODIGO = '" + this.codigo + "'";
                    command.ExecuteNonQuery();
    
                    ObjetoEnBD.transaction.Commit();
    
                    return true;
                }
                catch
                {
                    return false;
                }
            }

    Se que debo colocar los parámetros por separado, y no colocarlo todo en el string, como bien explicabas tu y Tuttini pero hasta la fecha queda listo, voy a empezar a implementar los parámetros por separado.

    Muchas Gracias, Pura Vida.

    • Marcado como respuesta Kent-15 jueves, 10 de octubre de 2013 16:35
    jueves, 10 de octubre de 2013 4:29