none
Hacer un Insert de registros en tabla SQL con campos cargados en un LIST RRS feed

  • Pregunta

  • Buenas tardes a todos. Lo que intento y quiero saber como lograrlo es hacer un Insert Into en Tabla tomando como NOMBRES de  CAMPO los que previamente se cargaron en una Lista. El tema es medio complejo de explicar. La aplicación que estoy creando, permite al Usuario Crear en tiempo de Ejecución sus propias tablas con sus diversos y diferentes campos. Una vez creadas, en otro Form, se cargan en un Combobox los nombres de todas esas tablas. Al seleccionar cualquiera de estas tablas en el Combo, automáticamente se carga en un List los NOMBRES de los campos de la Tabla seleccionada. (O sea, nunca se sabe exactamente que cantidad de campos y nombres tendrá C/Tabla, dado que la estructura la arma el Usuario). Por eso entiendo en mi desconocimiento, que no se pueda hacer con Store Procedures. La idea es (Cosa que ya hice), pasar los Nombres de Campo a un DatagridView (como encabezados de columna) y a partir de ahí, lograr el Insert y también la Posible modificación de datos, si hubiese que hacerlos en algún momento. El tema es, que hasta aquí llegué y ni idea de como seguir... Alguna ayuda Por favor. Muchas gracias. Trabajo con Visual Basic 2010 y SQL Express 2008 R2. Saludos.
    miércoles, 15 de abril de 2015 19:16

Respuestas

  • Aunque se podría hacer en un stored procedure con SQL dinámico y sp_ExecuteSql, no ofrece ninguna ventaja significativa en comparación con hacer lo mismo desde el código cliente. Tendrás que construir la consulta INSERT desde código en un string, y luego hacerla ejecutar con ExecuteNonQuery a través de un SqlCommand. Es decir, algo parecido a esto:

    string sentencia = "Insert into " + nombreDeTabla + " (" + listaDeColumnas + ") values (" + listaDeValores + ")";
    SqlCommand cmd = new SqlCommand(sentencia, conexion);
    cmd.ExecuteNonQuery();

    Donde, evidentemente, nombreDeTabla es una variable que contiene el nombre de tu tabla, listaDecolumnas es otra variable donde has metido los nombres de columnas separados por comas, y listaDeValores es otra variable donde has metido los valores a insertar separados por comas y adecuadamente formateados según su tipo (por ejemplo, entre comillas simples si son strings).

    EDITADO: Ojo, esa sentencia tal como la he escrito tiene riesgo de inyección de SQL. Si quieres refinarlo, puedes parametrizar la sentencia y luego añadir los parámetros al SqlCommand mediante un bucle. Solo vale para los valores de las columnas, el nombre de la tabla y los nombres de las columnas necesariamente tienen que concatenarse, no se pueden parametrizar.

    jueves, 16 de abril de 2015 5:43

Todas las respuestas

  • Aunque se podría hacer en un stored procedure con SQL dinámico y sp_ExecuteSql, no ofrece ninguna ventaja significativa en comparación con hacer lo mismo desde el código cliente. Tendrás que construir la consulta INSERT desde código en un string, y luego hacerla ejecutar con ExecuteNonQuery a través de un SqlCommand. Es decir, algo parecido a esto:

    string sentencia = "Insert into " + nombreDeTabla + " (" + listaDeColumnas + ") values (" + listaDeValores + ")";
    SqlCommand cmd = new SqlCommand(sentencia, conexion);
    cmd.ExecuteNonQuery();

    Donde, evidentemente, nombreDeTabla es una variable que contiene el nombre de tu tabla, listaDecolumnas es otra variable donde has metido los nombres de columnas separados por comas, y listaDeValores es otra variable donde has metido los valores a insertar separados por comas y adecuadamente formateados según su tipo (por ejemplo, entre comillas simples si son strings).

    EDITADO: Ojo, esa sentencia tal como la he escrito tiene riesgo de inyección de SQL. Si quieres refinarlo, puedes parametrizar la sentencia y luego añadir los parámetros al SqlCommand mediante un bucle. Solo vale para los valores de las columnas, el nombre de la tabla y los nombres de las columnas necesariamente tienen que concatenarse, no se pueden parametrizar.

    jueves, 16 de abril de 2015 5:43
  • Mil Gracias por tu aporte y pronta ayuda Alberto, probaré a ver que logro. Saludos cordiales.
    jueves, 16 de abril de 2015 18:34
  • Hola:

     Adicional a lo que comenta Alberto, anteriormente tuve la necesidad de hacer algo muy parecido a esto que deseas y para minimizar el riesgo de inyección SQL tuvimos que crear un patrón Regex que nos quitara todos los caracteres especiales de la sentencia SQL, por ejemplo &%-'=!" 

    Aquí un link con un ejemplo:

    Regex to remove all special characters from string?


    Saludos desde Monterrey, Nuevo León, México!!!

    jueves, 16 de abril de 2015 19:19
  • Muchas gracias José Luis, lo tendré en cuenta.

    Gracias por la Info...

    viernes, 17 de abril de 2015 11:39
  • Buenas tardes Alberto, ayer y hoy puede retomar y ver lo que me sugeriste. Primero quiero corregirme dado que los campos de las tablas que eventualmente se seleccionan en el COMBO TABLAS, llenan otro COMBO CAMPOS y NO un list. Disculpas por esto. Adjunto a esto, tengo en el Form un DGV, el cual SI paso como encabezados los nombres de los campos de la tabla seleccionada. El tema es, como en el Inset lograr que cada valor de cada Celda del DGV se guarde en el campo correspondiente. No se ni entiendo la forma de ir recorriendo cada Nombre de Campo que están en el combo a su vez en el encabezado del DGV y asignar cada valor de Celda a C/U de esos campos. Me imagino que será haciendo un Bucle For-Each, pero he buscado y probado hasta el cansancio y no doy en la tecla. Desde ya muchas gracias y disculpà las molestias

    Dim Value As Object = Me.cmbTablas.Text
                If (TypeOf Value Is DataRowView) Then Return
                Cadena = Convert.ToString(Value)
                ConsultaSelect = Nothing
                ConsultaSelect = "SELECT Column_Name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME= '" + Cadena + "'"
                Conexion = New SqlConnection(Cs)
                Conexion.Open()
                Ds = New DataSet
                Da = New SqlDataAdapter(ConsultaSelect, Conexion)
                Da.Fill(Ds, "Column_Name")
                Me.cmbCamposTablas.DataSource = Ds.Tables(0)
                Me.cmbCamposTablas.DisplayMember = ("Column_Name")
    Esto me carga el Combo Campos bien, pero hasta aquí llegue...


    sábado, 18 de abril de 2015 22:23
  • Buen día a todos. Tengo dos situaciones a ver quien me puede orientar o tender una mano. Algo está mal y no me doy cuenta que... Aquí dejo mi código...

    Try
                Dim Value As Object = Me.cmbTablas.Text
                If (TypeOf Value Is DataRowView) Then Return
                Cadena = Convert.ToString(Value)
                ConsultaSelect = Nothing
                ConsultaSelect = "SELECT Column_Name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME= '" + Cadena + "'"
                Conexion = New SqlConnection(Cs)
                Conexion.Open()
                Ds = New DataSet
                Da = New SqlDataAdapter(ConsultaSelect, Conexion)
                Da.Fill(Ds, "Column_Name")
                Me.cmbCamposTablas.DataSource = Ds.Tables(0)
                Me.cmbCamposTablas.DisplayMember = ("Column_Name")
    
                Dim Lista As New List(Of String)
                Dim Fila As DataRowView
                For Each Item As Object In cmbCamposTablas.Items
                    Fila = DirectCast(Item, DataRowView)
                    Lista.Add(CStr(Item("Column_Name")))
                    Columnas = Nothing
                    Columnas = (String.Join(",", Lista.ToArray))
                Next
                Conexion.Close()
    
                Dim i As Integer
                Dim x As Integer
                Dim DGVCell As DataGridViewCell
                While i < DataGridView1.Rows.Count
                    While x < DataGridView1.Columns.Count
                        DGVCell = DataGridView1.Rows(i).Cells(x)
                        Celdas = (CType(DGVCell.Value, String)) & "" & vbCrLf & ""
                        Me.cmbValores.Items.Add(Celdas).ToString()
                        Me.cmbValores.SelectedIndex = 0 '<-- Hasta acà Funciona bien, llena el combo Valores
                        ' con el contenido de cada celda de la primer fila del DGV. (Es lo que necesito)
    
                        Arreglo = New ArrayList
                        Arreglo.Add(Celdas.ToString())
    
                        Dim Var As String = Nothing
                        For T As Integer = 0 To Arreglo.Count - 1
                            Var = (String.Join(",", Arreglo.ToArray)) '<-- Aquì no me inserta las "," 
                            MsgBox(Var) '<-- Aquì me da uno a uno los valores de las celdas del DGV
                            'Ej: 1 2 3 4... Sin comas de separaciòn "," 
                            'Este MsgBox es solo pra ver que carga y como el ArrayList, dps. lo elimino
                        Next
                        x = x + 1
                    End While
                    i = i + 1
                End While

    El tema es que necesito insertar en un SELECT los VALUES según las columnas (Campos) que me arroja el LIST.

    Este es el Select:

    Sentencia = "Insert into " + Me.cmbTablas.Text + " (" + Columnas + ") Values (" + Celdas.ToString + ")"

    Cmd = New SqlCommand(Sentencia, Conexion)

    Conexion.Open()

    Cmd.ExecuteNonQuery()

    Conexion.Close()

    sábado, 2 de mayo de 2015 14:40