none
Desbordamiento de SqlDateTime - Celda de un datagridview RRS feed

  • Pregunta

  • Hola gente! Estoy haciendo algo en VB y les cuento que deseo insertar fechas desde un datagridview con un botón. Las quiero insertar en una base de datos en sql server, el date type de esta columna que recibe datos es Date. 

    En mis celdas de mi datagridview me aparecen las fecha como formato dd/MM/yyyy, pero cuando doy click al botón me aparece 

    "No se controló SqlTypeException. Desbordamiento de SqlDateTime. Debe estar entre 1/1/1753 12:00:00 AM y 12/31/9999 11:59:59 PM".

    Lo raro es que a pesar del error, las fechas se guardan con formato yyyy/mm/dd en mi tabla.

    Alguien me puede decir que pasa? No se como cambiar el valor de mi celda a formato yyyy/mm/dd para ver si ese es el error.

    Desde ya muchas gracias!

    sábado, 12 de octubre de 2019 19:46

Todas las respuestas

  • Idealmente, no deberías estar leyendo los datos directamente del DataGridView, sino del objeto que almacene por detrás los datos y se encuentre vinculado al DataGridView. Por ejemplo, lo más típico es usar un DataTable. El DataTable se enlaza al DataSource del DataGridView, y entonces se mantienen automáticamente sincronizados. Es decir, todo lo que haya en el DataTable se ve automáticamente en el DataGridView, y si tecleas algo en el DataGridView se copia automáticamente al DataTable. La consecuencia de esto es que nunca lees ni grabas nada en el DataGridView; todo lo haces sobre el DataTable.

    Si tienes las cosas así organizadas, lo que ocurre es que la columna de la Fecha la configuras para que sea de tipo DateTime en el DataTable. Al presentarse en pantalla, se convierte a texto utilizando el formato que ese equipo tenga configurado en el Panel de Control, salvo que tu programa haya cambiado el formato en el CurrenCulture. Si esto no te conviene, también puedes cambiar el formato en las propiedades de la columna del DataGridView. Esto te permite que la fecha se presente en pantalla en el formato que tú quieras, mientras que en memoria se guarda "sin formato", en el campo binario que hay en el DataTable de tipo DateTime.

    Cuando grabas en base de datos, grabas desde el DataTable, que proporciona el dato en binario, sin formato. Si grabas mediante un DataAdapter, el propio DataAdapter ya parametriza la sentencia y le pasa el valor binario al parámetro, por lo que nunca te tienes que preocupar del formato. Si usas un ORM para grabar los datos, pasa lo mismo: internamente se parametriza y no te preocupas del formato. Si grabas "a mano", escribiendo la sentencia SQL y mandándola ejecutar con un SqlCommand, entonces lo mismo: le pasas el DateTime en binario al parámetro (porque estás parametrizando tus sentencias, ¿verdad? ¿No estarás cometiendo el error de concatenar el texto?). Pues bien, si asignas el DateTime al parámetro queda en binario en todo momento, sin que nunca se convierta en string, por lo que no llega a existir nunca ningún formato y no tienes que preocuparte por ello.

    sábado, 12 de octubre de 2019 21:03
  • Idealmente, no deberías estar leyendo los datos directamente del DataGridView, sino del objeto que almacene por detrás los datos y se encuentre vinculado al DataGridView. Por ejemplo, lo más típico es usar un DataTable. El DataTable se enlaza al DataSource del DataGridView, y entonces se mantienen automáticamente sincronizados. Es decir, todo lo que haya en el DataTable se ve automáticamente en el DataGridView, y si tecleas algo en el DataGridView se copia automáticamente al DataTable. La consecuencia de esto es que nunca lees ni grabas nada en el DataGridView; todo lo haces sobre el DataTable.

    Si tienes las cosas así organizadas, lo que ocurre es que la columna de la Fecha la configuras para que sea de tipo DateTime en el DataTable. Al presentarse en pantalla, se convierte a texto utilizando el formato que ese equipo tenga configurado en el Panel de Control, salvo que tu programa haya cambiado el formato en el CurrenCulture. Si esto no te conviene, también puedes cambiar el formato en las propiedades de la columna del DataGridView. Esto te permite que la fecha se presente en pantalla en el formato que tú quieras, mientras que en memoria se guarda "sin formato", en el campo binario que hay en el DataTable de tipo DateTime.

    Cuando grabas en base de datos, grabas desde el DataTable, que proporciona el dato en binario, sin formato. Si grabas mediante un DataAdapter, el propio DataAdapter ya parametriza la sentencia y le pasa el valor binario al parámetro, por lo que nunca te tienes que preocupar del formato. Si usas un ORM para grabar los datos, pasa lo mismo: internamente se parametriza y no te preocupas del formato. Si grabas "a mano", escribiendo la sentencia SQL y mandándola ejecutar con un SqlCommand, entonces lo mismo: le pasas el DateTime en binario al parámetro (porque estás parametrizando tus sentencias, ¿verdad? ¿No estarás cometiendo el error de concatenar el texto?). Pues bien, si asignas el DateTime al parámetro queda en binario en todo momento, sin que nunca se convierta en string, por lo que no llega a existir nunca ningún formato y no tienes que preocuparte por ello.

    Te explico, al datagridview lo uso como calculador, una vez que el cálculo es de mi agrado, ahí recién insertaría los datos a la tabla. Igual puedo usar DataTable en ese caso?
    sábado, 12 de octubre de 2019 22:10
  • Te explico, al datagridview lo uso como calculador, una vez que el cálculo es de mi agrado, ahí recién insertaría los datos a la tabla. Igual puedo usar DataTable en ese caso?

    Desde el punto de vista de hacer los cálculos sí que podrías usar el DataTable, porque tiene en todo momento una copia exacta de los datos del datagridview. Pero puede ser que no te resulte práctico si estás interceptando los eventos del DataGridView para hacer cálculos cuando ocurran ciertas cosas, como por ejemplo un cambio de celda. En ese caso, prescindamos del datatable y volvamos al datagridview.

    Para resolver el problema de las fechas, una vez que leas una fecha desde el datagridview (que presumo la recibes como un String), hay que convertirla a DateTime. Para ello dispones de todo un surtido de funciones de conversión, desde el básico DateTime.Parse que siempre trata de interpretarla conforme con el formato de fecha que haya en el CurrentCulture, hasta las sobrecargas del Parse y TryParse y TryParseExact, que te permiten especificar la cultura y/o el formato y controlar si el dato introducido es o no es válido conforme con dicho formato.

    Una vez que ya has convertido la fecha en DateTime, ya la tenemos en binario y sin formato. Este valor de tipo DateTime se lo pasamos directamente al parámetro de la sentencia de inserción en base de datos, y de esa forma no hay que preocuparse del formato en ningún momento ya que todo es binario.

    • Propuesto como respuesta Pablo Rubio martes, 15 de octubre de 2019 15:33
    domingo, 13 de octubre de 2019 8:24