Está en la página 1de 16

Como insertar fechas en mi base de datos desde visual

studio.net 2008
Foros de Desarrollo
 > 
Lenguaje VB.NET

Pregunta

Inicie sesión para votar

Hola tengo que hacer una insercion de tres datos en mi base de datos,

pero uno es un dato de fecha y a la hora de hacer la insercion me arroja el siguiente error, lo cual no se
poque :

The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value. The
statement has been terminated.

alguien me podria ayudar el codigo que tengo es el siguiente:

cadena.Open()

Dim coman1 As New SqlCommand("insert into


Solic_Entradas(Fecha_Solic,Ficha_Auto,Ficha_Recib)values('" &
DTP_Fecha_Solic.Value.ToShortDateString & "'," &txt_FichaA.Text & "," &
Txt_Ficha_reci.Text & ")", cadena)

coman1.ExecuteNonQuery()

cadena.close()

en mi base de datos tengo el campo Fecha_Solic como datetime

DORI

jueves, 14 de octubre de 2010 14:55

Responder

|
Citar

Dios_esfiel

15 Puntos

Respuestas

Inicie sesión para votar

"jtorrecilla" preguntó:

> para que vas a enviar al procedimiento almacenado las fechas


> como string, si las puedes enviar como fechas directamente?

Tanto como enviar directamente, se pueden enviar. Pero si utilizas el método AddWithValue, en realidad
no le estás pasando un valor DateTime, String, Integer, Long, etc.; le estás pasando un valor del tipo
genérico «Object», que en alguna parte se convertirá en un valor válido correspondiente al tipo de dato que
espera el campo de la tabla de SQL Server. Por tanto, tarde o temprano hay que hacer una conversión, bien
explícita o implícita.

Pero a lo mejor habría que preguntarse qué es lo correcto: ¿enviar un tipo Object que almacena un valor
DateTime que depende de la cultura actual, o enviar un valor Object que almacene una cadena alfanumérica
que cumpla con el estándar internacional basado en la normal ISO 8601?

Un valor DateTime depende de la configuración regional de Windows, y el valor SET LANGUAGE de T-


SQL especifica el idioma de entorno de la sesión de SQL Server, por tanto, dependiendo del idioma de la
sesión, así se determinará los formatos DateTime que puede admitir SQL Server.

Para no liarse uno con temas raros, entiendo que en mi opinión lo correcto sería ajustarse a un estándar
internacional admitido, como puede ser el formato ISO 8601, y así es como se indica en los Libros en
Pantalla de Microsoft SQL Server:

[...] La ventaja de utilizar el formato ISO 8601 es que se trata de un estándar internacional con una
especificación que evita ambigüedades. Asimismo, este formato no se ve afectado por los parámetros SET
DATEFORMAT o SET LANGUAGE.[...]

Los tipos de datos DateTime, SmallDateTime, Date, y aquellos otros relacionados con fechas y horas,
admiten la normal ISO 8601, lo que significa que podemos especificar un valor de fecha como una cadena
alfanumérica en formato YYYYMMDD, o bien, YYYY-MM-DD, sin necesidad de hacer cualquier tipo de
conversión.
Por todo lo anterior, es por lo que entiendo que es correcto lo que ha comentado el usuario «gian2051», en
cuanto a enviar un valor alfanumérico en lugar de un valor DateTime, porque si el valor alfanumérico se
adapta a la norma ISO 8601, ya no es necesario que nos preocupemos de cualquier configuración regional
existente en Windows o en SQL Server.

Y en cuanto a utilizar procedimientos almacenados en lugar de consultas parametrizadas, no voy yo a


explicar aquí la ventana que supone porque de todos es bien sabido. No obstante, solamente diré que el
procedimiento almacenado ya se encuentra compilado y almacenado en la base de datos, y una consulta
parametrizada hay que compilarla cada vez que se ejecute. Al utilizar un procedimiento almacenado,
solamente hay que pasarle los valores que aquel espera.

Creamos un procedimiento almacenado que admite un valor VarChar que utilizaremos para añadir una
fecha a un campo definido con el tipo de dato «Date»

     CREATE PROCEDURE NombreProcedimiento


             @Fecha varchar(10)
     AS
     BEGIN
             INSERT INTO Fechas (Fecha) VALUES (@Fecha)
     END
     GO

Como podréis observar, tampoco es necesario hacer una conversión al tipo de dato Date en el propio
procedimiento almacenado.

Para insertar una fecha desde nuestra aplicación de Visual Basic, simplemente ejecutaríamos:

        Try
            Using cnn As New SqlConnection( _
                "Data Source=.\SQLExpress;Initial Catalog=Prueba;Integrated Security=SSPI")

                Dim cmd As SqlCommand = cnn.CreateCommand()

                cmd.CommandText = "NombreProcedimiento"


                cmd.CommandType = CommandType.StoredProcedure

                cmd.Parameters.Add("@Fecha", SqlDbType.VarChar).Value = "20101016"

                cnn.Open()

                Dim n As Integer = cmd.ExecuteNonQuery()

                MessageBox.Show(CStr(n))

            End Using

        Catch ex As Exception


            MessageBox.Show(ex.Message)

        End Try

Yo desde luego no me voy a complicar la vida con las fechas. Cuando trabajo con SQL Server, las fechas
las especifico en formato 'YYYYMMDD', y cuando lo haga con Access, en formato americano
#MM/DD/YYYY#.

Un saludo

Enrique Martínez [MS MVP - VB]

sábado, 16 de octubre de 2010 11:49

Responder

Citar

Enrique M. Montejo

(MVP)

56.690 Puntos

Inicie sesión para votar

"gian2051" me preguntó:

> Lo que te refieres a  tarde o temprano hay que hacer una conversión,
> bien explícita o implícita. es hacer por ejemplo la conversion antes
> de agregarlo(convert(date, @fecha,120))?

No. En ese párrafo concreto, me refiero a que será el compilador de Visual Basic, o el propio SQL Server
(no sé quién se encargará de ello, aunque entiendo que será éste último), hará la conversión necesaria del
valor Object al valor esperado por el tipo de dato del campo.

Como he comentado en mi respuesta, si el formato de fecha lo especificas como una cadena alfanumérica
basada en el formato ISO 8601, tú no tienes que hacer ninguna conversión.
> Y como seria el tipo generico object??

El tipo genérico «Object» es toda aquella variable objeto que declares utilizando el tipo de dato «Object»:

   Dim variable As Object

En .NET, todos los objetos derivan directa o indirectamente de la clase «Object», por tanto, a una variable
Object le puedes asignar cualquier referencia de otro objeto:

  variable = New DataSet()

Pero no al contrario, salvo que se haga una conversión explícita:

  Dim variable As Object

  Dim ds As New DataSet()

  ds = DirectCast(variable, DataSet)

Por supuesto, si el valor de la variable Object no se puede convertir a DataSet, se obtendrá la oportuna
excepción en tiempo de ejecución, por mucha conversión explícita que se haya realizado. :-)

Enrique Martínez [MS MVP - VB]

domingo, 17 de octubre de 2010 7:37

Responder

Citar

Enrique M. Montejo

(MVP)

56.690 Puntos

1
Inicie sesión para votar

"jtorrecilla" escribió:

> pero si le pasas un object sin hacer la conversión a tipo fecha, en este caso,
> cuando hagas la inserción te va a provocar un error, de ahi que asumiendo que
> utiliza un control de tipo DateTimePicker y su propiedad Value,
> sobreentienda que la fecha es correcta.

Me vas a disculpar, pero ya he leído tu respuesta 20 veces y todavía no soy capaz de entender,
exactamente, lo que me quieres decir. :-(

¡Vamos a ver! Si el supuesto Object que le deseas pasar, contiene un objeto DataSet (por poner un ejemplo
un tanto descabellado), es normal que se obtenga una excepción tan grande como un camión. Lo extraño
sería que lo aceptase. :-D

Pero si ese Object, encapsula un valor DateTime válido, ¿por qué motivo se va a obtener una excepción?

Ante todo, que conste que respondí a tu respuesta porque le indicastes al usuario gian2051 lo siguiente:

    > para que vas a enviar al procedimiento almacenado las fechas
    > como string, si las puedes enviar como fechas directamente?

Y todo esto venía en relación a las respuestas que, tanto tú como Leandro Tuttini, le ofrecísteis a la usuaria
Doralina, donde le indicábais que utilizara el método «AddWithValue» de la propiedad Parameters del
objeto SqlCommand.

Como bien sabrás, el segundo parámetro del método «AddWithValue» se encuentra definido con el tipo de
dato Object; no se encuentra definido como Integer, String, DateTime, DataSet, etc., por tanto, tu no le
estás enviando una variable DateTime (que es un «tipo de dato por valor»), si no que le estás enviando un
«tipo de dato por referencia» (que es lo que almacena el objeto o la clase Object), por lo que en tiempo de
ejecución se tendrá que hacer lo que se conoce como una conversión «boxing»: la conversión de un tipo por
valor (Integer, Long, Single, Double, Decimal, DateTime) a una variable Object.

Pero como el valor DateTime convertido a Object, contiene un valor de fecha y hora válido, no se produce
ninguna excepción cuando se inserta en el campo DateTime de la tabla de la base de datos. Por supuesto, si
el valor del Object no contiene un valor DateTime válido, se produciría la excepción a la hora de efectuar la
inserción (en la base de datos), no cuando se efectúa la operación boxing (en tiempo de ejecución), ya que
una variable Object admite todos los tipos de datos, sean por valor o por referencia.

Yo, en ningún momento he hablado de enviar valores Object ni DateTime. Yo, solamente dije que prefiero
enviar a SQL Server los valores de fecha como un valor alfanumérico conforme al estandar ISO 8601, por
los motivos que indiqué en mi respuesta, y porque no deseo complicarme la vida. nada más. :-)

> PD: Al tratar temas en la conversación con usuarios distintos del autor,
> comentarte que si les respondes a ellos, no van a poder marcar la
> respuesta como bien sabes, y aunque tus respuestas son perfectamente
> válidas no están 100% relacionadas con el tema del usuario.

¡Bueno! Yo creo que mi respuesta sí está al 100 por 100 relacionada con el asunto que inició la usuaria
Doralina. ;-)
Tal y como te he comentado anteriormente, yo te respondí a tí por el comentario que le efectuastes al
usuario gian2051, ya que me pareció oportuno indicar los motivos de enviar a SQL Server la fecha en
formato alfanumérico.

Y en cuanto a que se marque o no mi respuesta como satisfactoria, la verdad es que me da exactamente


igual. ¡Hay tantas respuestas mías que no se han calificado como satisfactorias, que una más me da igual!

Aparte, va para una década el tiempo que llevo intentando ayudar a los usuarios de Visual Basic, y mi
preocupación es enseñarles, en la medida de mis posibilidades y conocimientos, a que hagan bien las cosas
y que sepan por qué se tienen que hacer así.

De todas maneras, y como me imagino que conocerás, también te digo que hay Moderadores para que
califiquen las respuestas de los usuarios, si ellos lo creen conveniente. ;-)

Enrique Martínez [MS MVP - VB]

lunes, 18 de octubre de 2010 10:02

Responder

Citar

Enrique M. Montejo

(MVP)

56.690 Puntos

Inicie sesión para votar

"doralina" me preguntó:

> ahora deseo hacer una consulta un select, donde consulto


> la fecha al hacerlo en el sql sale perfecto pero ahora
> lo deceo hacer desde visual...donde el dato de la fecha
> lo contiene un date timer picker con formato de fecha dd/MM/yyyy
>
> ya que de esa manera la quiero mostrar pero me marca el
> sigueinte error: The conversion of a char data type to a
> datetime data type resulted in an out-of-range datetime value.

Por eso no me complico yo la vida con los formatos de fecha. Envío la fecha como valor alfanumérico en
formato YYYYMMDD, y asunto resuelto.

Vamos a imaginar que deseas recuperar las facturas emitidas en la fecha seleccionada en el control
DateTimePicker.

Para ello, ejecutarías lo siguiente:

        Try
            Using cnn As New SqlConnection("cadena de conexión)

                Dim sql As String = "SELECT * FROM Facturas " & _


                                             "WHERE Fecha = @Fecha"

                ' Creamos el parámetro VarChar


                Dim param As SqlParameter = New SqlParameter("@Fecha", SqlDbType.VarChar)

                ' Le especificamos la fecha en el formato ISO 8601


                param.Value = String.Format("{0:yyyyMMdd}", DateTimePicker1.Value)

                ' Creamos el comando


                Dim cmd As SqlCommand = cnn.CreateCommand()

                ' Le asignamos la consulta SQL de selección


                cmd.CommandText = sql

                ' Añadimos el parámetro


                cmd.Parameters.Add(param)

                ' Creamos el adaptador de datos


                Dim da As New SqlDataAdapter(cmd)

                ' Creamos el objeto DataTable


                Dim dt As New DataTable("Facturas")

                ' Rellenamos el objeto DataTable


                da.Fill(dt)

                ' Mostramos los datos en un control DataGridView


                DataGridView1.DataSource = dt

            End Using

        Catch ex As Exception


            MessageBox.Show(ex.Message)
        End Try
    End Sub

Se entiende que el campo «fecha_solic» de tu tabla Entradas, está definido con algún tipo de dato de fecha
y hora de SQL Server, y que sólo guarda información de la fecha, es decir, no guarda valores de la hora.

Enrique Martínez [MS MVP - VB]

martes, 19 de octubre de 2010 13:34

Responder

Citar

Enrique M. Montejo

(MVP)

56.690 Puntos

Inicie sesión para votar

Prueba esto doralina:

cadena.Open()

using cmd as new SqlCommand(insert into


Solic_Entradas(Fecha_Solic,Ficha_Auto,Ficha_Recib)values(@fecha1,@ficha1,@ficha2)",cadena)

cmd.Parameters.AddWithValue("fecha1",DTP_Fecha_Solic.Value)

cmd.Parameters.AddWithValue("ficha1",txt_FichaA.Text)
cmd.Parameters.AddWithValue("ficha2",Txt_Ficha_reci.TExt)
cmd.ExecuteNonQuery()

end using

Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta
por favor marca las respuestas que te hayan ayudado como "Respuesta".
Si la respuesta te ha sido util Votala.
Mi Blog: Jtorrecilla
Enlace a Faq de Winforms en Ingles Muy bueno

jueves, 14 de octubre de 2010 14:58

Responder

Citar

jtorrecilla

(MVP)

27.075 Puntos

Inicie sesión para votar

hola

usa parametros

algo como esto

cadena.Open()
Dim query As String ="insert into Solic_Entradas(Fecha_Solic,Ficha_Auto,Ficha_Recib) " & _
                    "values (@fecha, @ficha, @ficharecib)"

Dim coman1 As New SqlCommand(query, cadena)


coman1.Patameters.AddWithValue("@fecha", DTP_Fecha_Solic.Value)
coman1.Patameters.AddWithValue("@ficha", txt_FichaA.Text)
coman1.Patameters.AddWithValue("@ficharecib", Txt_Ficha_reci.Text)

coman1.ExecuteNonQuery()
cadena.close()

saludos

Leandro Tuttini

Blog
Buenos Aires
Argentina

jueves, 14 de octubre de 2010 15:00

Responder

Citar

Leandro Tuttini

Baufest

(Partner, MVP)

537.865 Puntos

Todas las respuestas


0
Inicie sesión para votar

Prueba esto doralina:

cadena.Open()

using cmd as new SqlCommand(insert into


Solic_Entradas(Fecha_Solic,Ficha_Auto,Ficha_Recib)values(@fecha1,@ficha1,@ficha2)",cadena)

cmd.Parameters.AddWithValue("fecha1",DTP_Fecha_Solic.Value)

cmd.Parameters.AddWithValue("ficha1",txt_FichaA.Text)

cmd.Parameters.AddWithValue("ficha2",Txt_Ficha_reci.TExt)
cmd.ExecuteNonQuery()

end using

Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta
por favor marca las respuestas que te hayan ayudado como "Respuesta".
Si la respuesta te ha sido util Votala.
Mi Blog: Jtorrecilla
Enlace a Faq de Winforms en Ingles Muy bueno

jueves, 14 de octubre de 2010 14:58

Responder

Citar

jtorrecilla

(MVP)

27.075 Puntos


0

Inicie sesión para votar

hola

usa parametros

algo como esto

cadena.Open()

Dim query As String ="insert into Solic_Entradas(Fecha_Solic,Ficha_Auto,Ficha_Recib) " & _


                    "values (@fecha, @ficha, @ficharecib)"

Dim coman1 As New SqlCommand(query, cadena)


coman1.Patameters.AddWithValue("@fecha", DTP_Fecha_Solic.Value)
coman1.Patameters.AddWithValue("@ficha", txt_FichaA.Text)
coman1.Patameters.AddWithValue("@ficharecib", Txt_Ficha_reci.Text)

coman1.ExecuteNonQuery()
cadena.close()

saludos

Leandro Tuttini

Blog
Buenos Aires
Argentina

jueves, 14 de octubre de 2010 15:00

Responder

Citar

Leandro Tuttini

Baufest
(Partner, MVP)

537.865 Puntos

Inicie sesión para votar

salio a la perfeccion gracias jtorrecilla por tu ayuda... bless

DORI

jueves, 14 de octubre de 2010 15:20

Responder

Citar

Dios_esfiel

15 Puntos

Inicie sesión para votar

Hola leandro igual tu respuesta es otra opcion muy certera graciassssss por responder, que tengas un buen
dia

DORI
jueves, 14 de octubre de 2010 15:20

Responder

Citar

Dios_esfiel

15 Puntos

Inicie sesión para votar

hola:

yoo te aconsejaria usar procedimientos almacenados, por ejemplo en tu sql :proc_alm_registro que
reciba parametros varcar(10) en lugar date y luego que el mismo sql lo convierta a date, lo digo para
que tu fecha siempre se registre correctamente, en casos que por ejemplo, el sistema operativo sea de
diferente idioma o el sql.

Supongamos: si tu winform o webform manda la fecha a sql en este formato :14/10/2010(dmy


formato español) y tu sql cambia de idioma o recibiera solo el formato 10/14/2010 (mdy) es obvio que
saldria error. bueno ahi te va alguito:

create procedure proc_alm_registro


 @c_fecha varchar(10), @texto varchar(50)
 as
 
 declare @fecha date = convert(date, @c_fecha,120)
 --120 es el formato yyyymmdd: 2010/10/14
 /*cierto!! el texto es cualquiera cosa que desees,
 es para que la tabla del ejemplo no tenga una columna */

 insert into tabla(fecha,texto) values(@fecha,@texto)

Ahora en tu formulario; a la hora de ingresar la fecha podrias concatenarlo, algo asi:

dim fecha as string = fe.value.year & "-" & fe.value.month & "-" & fe.value.day

fe es un date time picker


Ahora como ingresas los parametros? bueno mas arriba esta la manera jeje. Veras que si lo haces de
esta manera te puedes ahorrar muchos problemas jejeje, incluso yo los tuve cuando mi servidor sql
estaba en ingles y mi compu español jejeje suerte

También podría gustarte