none
Problema con un Insert Into RRS feed

  • Pregunta

  • Hola amigos buenas tardes, tengo un detalle con INSERT INTO, quiero ejecutar el siguiente QUERY dentro de mi VB.NET:

    Consulta = INSERT INTO Registro_EQ (Codigo, Fechtran, Fechaini, Fechaexp, IDCONF, Descripcion, Marca, Modelo, Serie, ConLista, Porcentaje_cl, SinLista, Porcentaje_sl, Movible, Porcentaje_mv, Edificio, Porcentaje_ed, Automatico, Exceso, Porcentaje_ex, Asignacion, Estatus, IDUsuario)
    SELECT [Codigo] , [Fechtran], DATEADD(year, 1, Fechaini) as Fecha, DATEADD(year, 1, Fechaexp) as Fecha2,
       [IDCONF], [Descripcion], [Marca], [Modelo], [Serie], [ConLista], [Porcentaje_cl], [SinLista], [Porcentaje_sl], [Movible],
               [Porcentaje_mv], [Edificio], [Porcentaje_ed], [Automatico], [Exceso], [Porcentaje_ex], [Asignacion], [Estatus], [IDUsuario]
      FROM [Pru].[dbo].[Registro_EQ]
      WHERE Fechaini >= '" & MTBFechainiant.Text & "'" & "AND Fechaini < '" & MTBFechainiaper.Text & "'"

    Quiero ejecutarlo nada mas, con los datos correspondientes a los textbox, pero me manda el error siguiente:

    Error: The select list for the Insert statement contains more items than the insert list. The number of SELECT values muest match the number of INSERT columns.

    Tengo que poner VALUES(@Codigo, etc...)

    Y query.Parameters.AddwithValue("@Codigo", ?) pongo signo de interrogacion por que no tengo un txt con el valor.

    Simplemente lo unico que desdeseo es ejecutar el Query para aperturar el año, y que se haga internamente en la base de datos... espero haberme explicado y agradezco de ante mano su pronta Respuesta...

    Saludos y bendiciones!...


    _ José Ángel Salinas Paz

    lunes, 2 de diciembre de 2019 22:39

Respuestas

  • Hola JA Salinas:

    Porqué

    & "WHERE Fechaini >= '" & MTBFechainiant.Text & "'" & "AND Fechaini < '" & MTBFechainiaper.Text & "'"
                                                    

    Si ya sabes utilizar parámetros, ¿qué diferencia hay entre estos y los de insert?. Ninguna verdad, pues entonces, parametriza también esto.

    En cuanto al no pudiste, se hace así.

    Buscas el SQL Server Profiler, bien sea desde el icono de la aplicación, o desde el menú de herramientas del SQL Management Studio

    Al iniciar, te presenta un cuadro de dialogo de conexión.

     

    Realizas la conexión al servidor SQL y pulsas Conectar

    Escoges la plantilla en blanco y cambias a la pestaña de selección de eventos

    En selección de eventos, escoges TSQL, y marcas SQL BatchCompleted

    Preparas tu sentencia, en ejecución, y justo antes de pulsar el botón de insertar o como lo dispongas en tu aplicación.

    Pulsas ejecutar en el profiler.

    Verás como cuando lances la sentencia de inserción, el profiler, captura todas las sentencias que se envían al server.

    Para el profiler, seleccionas, linea por linea, hasta que encuentres la sentencia que buscas, y verás que en la ventana inferior, esta la sentencia TSQL que has escrito en vb.net, y verás si contiene todos los valores, que has definido, o si hay alguna anomalía, como te indica el motor. Y ya sabes, que el no falla. Si dice que no es que algo no.

    • Propuesto como respuesta Pablo Rubio miércoles, 4 de diciembre de 2019 19:00
    • Marcado como respuesta JA Salinas viernes, 6 de diciembre de 2019 16:36
    martes, 3 de diciembre de 2019 20:17
  • Hola JA Salinas:

    Mucho mejor.

    Desde mi punto de vista, hay otra cosa que pulir.

    Nunca pienses que el usuario va a introducir bien los datos, porque no ocurre, y te dejará sentencias erroneas, pantallazos y cosas de este estilo, simplemente porque los humanos tenemos los dedos torpes.

    Quiero decirte con esto, que no se le pasan sentencias al motor sql que nosotros podemos capturar en .NET.

    Por ejemplo me supongo que MTBFechainiaper será un valor tipo fecha (si no es ese, da igual, otro similar)

    Lo que se hace, es capturar en una variable el contenido del textBox, intentar convertirlo a fecha. Y si la conversión es correcta, entonces llamo al sql, pero si la conversion a fecha no funciona, le digo al usuario, lo que has introducido en tu caja de texto es un valor no admitido. Eso hace que tú código sea mucho más robusto.

    TryParse

    https://docs.microsoft.com/es-es/dotnet/api/system.datetime.tryparse?view=netframework-4.8

    Saludos

    • Marcado como respuesta JA Salinas viernes, 6 de diciembre de 2019 16:37
    viernes, 6 de diciembre de 2019 8:21

Todas las respuestas

  • Hola JA Salinas:

    El error te indica que tienes más columnas que valores, aunque realmente tienes 23 columnas y  en la select tienes 23 columnas, por tanto la única conclusión posible, es que un valor es null y no esta enviando null, Vb.net, esta omitiendolo de la lista.

    INSERT INTO Registro_EQ
     (Codigo
    , Fechtran
    , Fechaini
    , Fechaexp
    , IDCONF
    , Descripcion
    , Marca
    , Modelo
    , Serie
    , ConLista
    , Porcentaje_cl
    , SinLista
    , Porcentaje_sl
    , Movible
    , Porcentaje_mv
    , Edificio
    , Porcentaje_ed
    , Automatico
    , Exceso
    , Porcentaje_ex
    , Asignacion
    , Estatus
    , IDUsuario
     )
           SELECT [Codigo]
                , [Fechtran]
                , DATEADD(year, 1, Fechaini) AS Fecha
                , DATEADD(year, 1, Fechaexp) AS Fecha2
                , [IDCONF]
                , [Descripcion]
                , [Marca]
                , [Modelo]
                , [Serie]
                , [ConLista]
                , [Porcentaje_cl]
                , [SinLista]
                , [Porcentaje_sl]
                , [Movible]
                , [Porcentaje_mv]
                , [Edificio]
                , [Porcentaje_ed]
                , [Automatico]
                , [Exceso]
                , [Porcentaje_ex]
                , [Asignacion]
                , [Estatus]
                , [IDUsuario]
           FROM [Pru].[dbo].[Registro_EQ]

    Si es el código o cualquier otra columna, como pareces indicar, puedes enviarle un DbNullValue.

    No has indicado tú gestor de base de datos, pero si es Sql Server no se pone el values en la sentencia, pero si deberías siempre, utilizar Parámetros

    Te dejo un enlace donde verás como se inserta con DbNull.Value

    https://stackoverflow.com/questions/4722705/how-to-insert-null-into-database-if-form-field-is-empty

    Un saludo

    martes, 3 de diciembre de 2019 5:55
  • Hola Javi gracias por responder, mira no tengo ningun valor nulo en las columnas, no se si el Query es compuesto primero por un INSER INTO y Luego un Select, no se si lo tenga que hacer por separado y en el INSERT INTO agregar VALUES y todo lo que con lleva, lo unico que quiero es ejecutar el Query ya que si lo hago desde SQL SERVER del Select toma la informacion y la Inserta con el INSERT... no se si me explico...

    Gracias de nuevo por tu apoyo... saludos!...


    _ José Ángel Salinas Paz

    martes, 3 de diciembre de 2019 15:27
  • Hola JA Salinas:

    Los dos formatos son válidos, tanto

    Insert into tabla (detalleColumnas) Select campos from tutabla 

    inserta 1 o varios registros.

    Pero si haces Insert into tabla (detalleColumnas) values

    (valorEscalar, valorEscalar);

    Entonces tienes que hacer un bucle de inserts.

    Pero piensa que el error que te muestra el Sql es por lo que te he comentado.

    Una manera de asegurarte de eso, es utilizando el Sql server Profiler, para saber explicitamente lo que le esta llegando, y así sabes por que no funciona.

    Si no sabes como funciona el profiler, te dejo un enlace a un artículo, donde lo utilizo, aunque para otra cosa, pero se usa del mismo modo. Verás el código explicito de insercción que le envia tu aplicación al Sql server. (Hay muchos videos de como usarlo)

    https://javifer2.wordpress.com/2019/10/27/case-vs-choose-es-lo-mismo-o-no-analisis-de-rendimiento-con-sql-server-profiler/

    • Propuesto como respuesta Pablo Rubio miércoles, 4 de diciembre de 2019 19:00
    martes, 3 de diciembre de 2019 16:15
  • Else
                                                Try
                                                    TApertura.Start()
                                                    'Insertar datos en Tabla Registro_EQ
                                                    consulta = "SELECT [Codigo] , [Fechtran], DATEADD(year, 1, Fechaini) as Fecha, DATEADD(year, 1, Fechaexp) as Fecha2," _
                                                        & "[IDCONF], [Descripcion], [Marca], [Modelo], [Serie], [ConLista], [Porcentaje_cl], [SinLista], [Porcentaje_sl], [Movible]," _
                                                        & "[Porcentaje_mv], [Edificio], [Porcentaje_ed], [Automatico], [Exceso], [Porcentaje_ex], [Asignacion], [Estatus], [IDUsuario]" _
                                                        & "FROM [Sedeumse].[dbo].[Registro_EQ]" _
                                                        & "WHERE Fechaini >= '" & MTBFechainiant.Text & "'" & "AND Fechaini < '" & MTBFechainiaper.Text & "'"
                                                    query = New SqlCommand(consulta, ConexionconBD)
                                                    ejecutar = query.ExecuteReader
    
                                                    consulta2 = "INSERT INTO Registro_EQ (Codigo, Fechtran, Fechaini, Fechaexp, IDCONF, Descripcion, Marca, Modelo, Serie, ConLista, Porcentaje_cl, SinLista, Porcentaje_sl, Movible," _
                                                        & "Porcentaje_mv, Edificio, Porcentaje_ed, Automatico, Exceso, Porcentaje_ex, Asignacion, Estatus, IDUsuario)" _
                                                        & "VALUES(@Codigo, @Fechtran, @Fechaini, @Fechaexp, @IDCONF, @Descripcion, @Marca, @Modelo, @Serie, @ConLista, @Porcentaje_cl, @SinLista, @Porcentaje_sl, @Movible, @Porcentaje_mv, @Edificio, @Porcentaje_ed, @Automatico, @Exceso, @Porcentaje_ex, @Asignacion, @Estatus, @IDUsuario)"
                                                    query2 = New SqlCommand(consulta2, ConexionconBD2)
    
    
                                                    While ejecutar.Read()
                                                        query2.Parameters.Clear()
                                                        query2.Parameters.AddWithValue("@Codigo", ejecutar("Codigo"))
                                                        query2.Parameters.AddWithValue("@Fechtran", ejecutar("Fechtran"))
                                                        query2.Parameters.AddWithValue("@Fechaini", ejecutar("Fecha"))
                                                        query2.Parameters.AddWithValue("@Fechaexp", ejecutar("Fecha2"))
                                                        query2.Parameters.AddWithValue("@IDCONF", ejecutar("IDCONF"))
                                                        query2.Parameters.AddWithValue("@Descripcion", ejecutar("Descripcion"))
                                                        query2.Parameters.AddWithValue("@Marca", ejecutar("Marca"))
                                                        query2.Parameters.AddWithValue("@Modelo", ejecutar("Modelo"))
                                                        query2.Parameters.AddWithValue("@Serie", ejecutar("Serie"))
                                                        query2.Parameters.AddWithValue("@ConLista", ejecutar("ConLista"))
                                                        query2.Parameters.AddWithValue("@Porcentaje_cl", ejecutar("Porcentaje_cl"))
                                                        query2.Parameters.AddWithValue("@SinLista", ejecutar("SinLista"))
                                                        query2.Parameters.AddWithValue("@Porcentaje_sl", ejecutar("Porcentaje_sl"))
                                                        query2.Parameters.AddWithValue("@Movible", ejecutar("Movible"))
                                                        query2.Parameters.AddWithValue("@Porcentaje_mv", ejecutar("Porcentaje_mv"))
                                                        query2.Parameters.AddWithValue("@Edificio", ejecutar("Edificio"))
                                                        query2.Parameters.AddWithValue("@Porcentaje_ed", ejecutar("Porcentaje_ed"))
                                                        query2.Parameters.AddWithValue("@Automatico", ejecutar("Automatico"))
                                                        query2.Parameters.AddWithValue("@Exceso", ejecutar("Exceso"))
                                                        query2.Parameters.AddWithValue("@Porcentaje_ex", ejecutar("Porcentaje_ex"))
                                                        query2.Parameters.AddWithValue("@Asignacion", ejecutar("Asignacion"))
                                                        query2.Parameters.AddWithValue("@Estatus", ejecutar("Estatus"))
                                                        query2.Parameters.AddWithValue("@IDUsuario", ejecutar("IDUsuario"))
                                                        query2.Connection = ConexionconBD
                                                        query2.ExecuteNonQuery()
                                                    End While
                                                    ejecutar.Close()

    Mira Javier lo tuve que hacer de esta manera, para que me funcione ... como tu dices tuve que hacer un bucle de Inserts, porque directa no pude hacerlo me marca el error que te puse arriba... Gracias de nuevo por atender, espero tu comentario de este codigo..

    Saludos y bendiciones!...


    _ José Ángel Salinas Paz


    • Editado JA Salinas martes, 3 de diciembre de 2019 17:52
    • Propuesto como respuesta Pablo Rubio miércoles, 4 de diciembre de 2019 19:00
    martes, 3 de diciembre de 2019 17:48
  • Hola JA Salinas:

    Porqué

    & "WHERE Fechaini >= '" & MTBFechainiant.Text & "'" & "AND Fechaini < '" & MTBFechainiaper.Text & "'"
                                                    

    Si ya sabes utilizar parámetros, ¿qué diferencia hay entre estos y los de insert?. Ninguna verdad, pues entonces, parametriza también esto.

    En cuanto al no pudiste, se hace así.

    Buscas el SQL Server Profiler, bien sea desde el icono de la aplicación, o desde el menú de herramientas del SQL Management Studio

    Al iniciar, te presenta un cuadro de dialogo de conexión.

     

    Realizas la conexión al servidor SQL y pulsas Conectar

    Escoges la plantilla en blanco y cambias a la pestaña de selección de eventos

    En selección de eventos, escoges TSQL, y marcas SQL BatchCompleted

    Preparas tu sentencia, en ejecución, y justo antes de pulsar el botón de insertar o como lo dispongas en tu aplicación.

    Pulsas ejecutar en el profiler.

    Verás como cuando lances la sentencia de inserción, el profiler, captura todas las sentencias que se envían al server.

    Para el profiler, seleccionas, linea por linea, hasta que encuentres la sentencia que buscas, y verás que en la ventana inferior, esta la sentencia TSQL que has escrito en vb.net, y verás si contiene todos los valores, que has definido, o si hay alguna anomalía, como te indica el motor. Y ya sabes, que el no falla. Si dice que no es que algo no.

    • Propuesto como respuesta Pablo Rubio miércoles, 4 de diciembre de 2019 19:00
    • Marcado como respuesta JA Salinas viernes, 6 de diciembre de 2019 16:36
    martes, 3 de diciembre de 2019 20:17
  • Hola JA Salinas:

    Ojo el profiler, es una herramienta que tiene mucho coste. Si el servidor esta en producción, no lo utilices.

    Si esta en un servidor con otras bases de datos, y ves que te devuelve mucha información, puedes filtrar por base de datos, en la pantalla de selección de eventos pulsando filtros de columna.

    Buscas DataBase_id

    y en el server buscas entre Select database_id, name from sys.databases la que encaje con tú base y el número que te devuelva, lo pones en esa cajita.

    Saludos

    martes, 3 de diciembre de 2019 20:20
  • Correcto eso hare muchas gracias de nuevo Bendiciones para ti y tu familia!...

    _ José Ángel Salinas Paz

    jueves, 5 de diciembre de 2019 17:01
  • Hola Javier entonces quedaría como sigue:

     consulta = "SELECT [Codigo] , [Fechtran], DATEADD(year, 1, Fechaini) as Fecha, DATEADD(year, 1, Fechaexp) as Fecha2," _
                                                        & "[IDCONF], [Descripcion], [Marca], [Modelo], [Serie], [ConLista], [Porcentaje_cl], [SinLista], [Porcentaje_sl], [Movible]," _
                                                        & "[Porcentaje_mv], [Edificio], [Porcentaje_ed], [Automatico], [Exceso], [Porcentaje_ex], [Asignacion], [Estatus], [IDUsuario]" _
                                                        & "FROM [Sedeumse].[dbo].[Registro_EQ]" _
                                                        & "WHERE Fechaini >= @MTBFechainiante AND Fechaini < @Fechainiaper"
                                                 query = New SqlCommand(consulta, ConexionconBD)
                                                 query.Parameters.AddWithValue("@MTBFechainiante", MTBFechainiante.Text)
                                                 query.Parameters.AddWithValue("@Fechainiaper", MTBFechainiaper.Text)
                                                 ejecutar = query.ExecuteReader

    La explicacion del SQL Server ProFiler la revise en el link que me pusiste anteriormente, y bueno con esto que pusiste ahora quedo mas que claro... voy hacer pruebas con ello...

    Nuevamente agradezco tu ayuda y tu apoyo...

    Saludos y bendiciones!...


    _ José Ángel Salinas Paz

    jueves, 5 de diciembre de 2019 17:27
  • Y query.Parameters.AddwithValue("@Codigo", ?) pongo signo de interrogacion por que no tengo un txt con el valor.

    Si no tienes un valor la forma correcta de pasar es VBNULL.VALUE


    Si necesitas ayuda sube tu avance de otro modo no puedo ayudarte , Suerte!

    jueves, 5 de diciembre de 2019 17:33
  • Y query.Parameters.AddwithValue("@Codigo", ?) pongo signo de interrogacion por que no tengo un txt con el valor.

    Si no tienes un valor la forma correcta de pasar es VBNULL.VALUE


    Si necesitas ayuda sube tu avance de otro modo no puedo ayudarte , Suerte!

    La respuesta anterior es en cuanto a la aclaracion de la Respuesta anterior de Javier solo estoy citando a lo que el me puso ... gracias amigo por contestar... lo de mas esta mas arriba... 

    Saludos y bendiciones!...


    _ José Ángel Salinas Paz

    jueves, 5 de diciembre de 2019 17:40
  • Hola JA Salinas:

    Mucho mejor.

    Desde mi punto de vista, hay otra cosa que pulir.

    Nunca pienses que el usuario va a introducir bien los datos, porque no ocurre, y te dejará sentencias erroneas, pantallazos y cosas de este estilo, simplemente porque los humanos tenemos los dedos torpes.

    Quiero decirte con esto, que no se le pasan sentencias al motor sql que nosotros podemos capturar en .NET.

    Por ejemplo me supongo que MTBFechainiaper será un valor tipo fecha (si no es ese, da igual, otro similar)

    Lo que se hace, es capturar en una variable el contenido del textBox, intentar convertirlo a fecha. Y si la conversión es correcta, entonces llamo al sql, pero si la conversion a fecha no funciona, le digo al usuario, lo que has introducido en tu caja de texto es un valor no admitido. Eso hace que tú código sea mucho más robusto.

    TryParse

    https://docs.microsoft.com/es-es/dotnet/api/system.datetime.tryparse?view=netframework-4.8

    Saludos

    • Marcado como respuesta JA Salinas viernes, 6 de diciembre de 2019 16:37
    viernes, 6 de diciembre de 2019 8:21
  • Hola Javi

    Si exacto es una fecha que el usuario introduce... es un MaskTextBox solo que yo asi lo abrevio para identificarlo je!.. 

    Correcto amigo voy revisar el documento y si tengo alguna duda te buscare... agradezco mucho tu apoyo y deseo que Dios te bendiga a ti a tu familia...  y felices fiestas!...

    Saludos!...


    _ José Ángel Salinas Paz

    viernes, 6 de diciembre de 2019 16:41