none
Inserto registros con C# y, en ocasiones, se corrompe la tabla RRS feed

  • Pregunta

  • Estoy impresionado. Llevo 20 años programando y nunca había visto algo así. Tengo un programa que enlaza con una DLL escrita en C#. En esta librería me conecto a una base de datos Access a través de ODBC. En ocasiones todo va bien pero otras veces el programa escribe registros que puedo verlos abriendo acces pero están corruptos. Sé que están corruptos porque si hay una compactación/reparación de la base de datos desaparecen esos registros.

    Estoy usando las sentencias de C#

                szExecute = String.Format(SolutionConstants.DB_INSERT_READER, pCode, pAux, pCrc, pTid);

                /* Se inserta el registro en la base de datos */
                OdbcCommand.CommandText = szExecute;
                OdbcCommand.ExecuteNonQuery();

    ¿Alguien sabe de problemas relacionados con integridad de datos en C#?

    Muchísimas gracias

    jueves, 27 de febrero de 2020 18:50

Todas las respuestas

  • Estoy impresionado. Llevo 20 años programando y nunca había visto algo así.

    Yo llevo 40 años programando, y han pasado más de 20 desde la última vez que manejé Access por ODBC. Pero en los tiempos en los que lo usaba, sobre todo cuando era una aplicación multiusuario en red, el fichero Access se corrompía cada dos por tres y había que andarlo reparando. La causa más común de que esto sucediese era una interrupción inesperada de la aplicación que estaba grabando en Access, con independencia del lenguaje en el que estuviese escrita (en aquellos tiempos todavía no teníamos C#). Pero otras veces también se corrompía de manera completamente inexplicable, aun habiendo cerrado la aplicación ordenadamente en todos los puestos.

    Con OleDb se alivia un poco la situación, pero tampoco es ninguna maravilla en este sentido. Si es una aplicación multiusuario, la única solución realmente fiable es la de olvidarse de sistemas que funcionen mediante compartición de archivos y usar en su lugar un servicio de base de datos "de verdad", aunque no sea nada más que un simple SQL Server Express.

    jueves, 27 de febrero de 2020 20:57
    Moderador
  • Gracias Alberto por tu comentario. Lo cierto es que los problemas han venido sólamente cuando he incorporado una dll al programa que trabaja en C#. La corrupción viene desde el único INSERT que hace esta dll en C#.

    Mi pregunta más concreta (puesto que no conozco muy bien C#) sería esta. Ahora estoy haciendo un insert con el código:

                /* Se compone la cadena de inserción en la base de datos */
                szExecute = String.Format("Insert Into TABLE(code, data, crc, tid) VALUES ('{0}', '{1}', '{2}', '{3}')", pcODE, pData, pCrc, pTid);

                /* Se inserta el tag en la base de datos */
                OdbcCommand.CommandText = szExecute;
                OdbcCommand.ExecuteNonQuery();

    ¿Estoy haciéndolo bien? ¿... o existe un método mejor de hacer una inserción en C#?

    Muchas gracias por los consejos!
    Atentamente

    Miguel Ángel.

    jueves, 27 de febrero de 2020 21:43
  • o existe un método mejor de hacer una inserción en C#?

    Bueno, sería preferible parametrizar la sentencia en lugar de usar manipulación de strings para concatenar los datos en la Insert. Pero aunque no esté parametrizada, eso no es motivo para que se corrompa el fichero. El problema tiene que estar en algún otro sitio. ¿Puede ser que exista algún caso en el que se quede sin cerrar la conexión? ¿O tal vez que se detenga inesperadamente el programa en el momento en el que estaba grabando?
    jueves, 27 de febrero de 2020 22:15
    Moderador
  • Bueno, justo ahora estaba añadiendo una línea para cerrar la conexión (perdón pero no me manejo nada bien en C#). Quedaría:

                /* Se abre la conexión, si estaba cerrada */
                if (OdbcConnect.State != ConnectionState.Open)
                {
                    OdbcCommand.Connection.Open();
                }
                /* Se compone la cadena de inserción en la base de datos */
                szExecute = String.Format("Insert Into TABLE(code, data, crc, tid) VALUES ('{0}', '{1}', '{2}', '{3}')", pcODE, pData, pCrc, pTid);

                /* Se inserta el tag en la base de datos */
                OdbcCommand.CommandText = szExecute;
                OdbcCommand.ExecuteNonQuery();

                /* Se cierra la línea de comando */
                OdbcCommand.Connection.Close();
        

    ¿Puede ser el hecho de que no hiciera el Close() por lo que se corrompía la tabla? Lo pasaré mañana a real para que lo prueben a ver si era eso.

    Gracias siempre por el apoyo, muchas gracias.

    jueves, 27 de febrero de 2020 22:24