none
Usar un procedimiento almacenado para guardar en varias tablas. RRS feed

  • Pregunta

  • Buenos dias estimados amigos para aquí para solicitar una ayuda, pasa lo siguiente.

    Quiero  hacer un procedimiento almacenado insert en sql server donde yo le pase como parámetro en vb.net el nombre de la tabla y nombre del campo id y el nombre del campo descripción 

    Muchas gracias por la ayuda.

    viernes, 6 de julio de 2018 15:21

Respuestas

  • Es algo bastante "feo" porque las sentencias SQL no permiten parametrizar el nombre de la tabla, asi que hay que concatenarlo todo en un string y luego mandarlo ejecutar. Esto, aparte de ser poco eficiente porque no se guarda pre-optimizado, tiene el riesgo de que es sensible a los ataques de inyeccion de SQL, asi que tienes que cerciorarte de que has validado previamente los datos que se le pasan al procedimiento.

    Dicho eso, el codigo que habria que meter en el procedimiento es mas o menos asi:

    declare @sql nvarchar(1000)
    set @sql = N'Insert into ' + @tabla + '(Id, Descripcion) Values(' + cast(Id as varchar) + ',' + '''' + descripcion + ''')'
    exec sp_executesql @sql
    

    Admite muchas optimizaciones, por ejemplo, el Id y la descripcion se podrian parametrizar dentro del sp_exeutesql. Aparte de eso, lo he escrito de memoria sin probarlo y es facil que contenga algun errorcilo que tendrias que corregir.

    Pero dicho eso, la cuestion es por que quieres hacer esto dentro de un procedimiento almacenado, dado que al tener que usar sql dinamico se pierden todas las ventajas de los procedimientos almacenados. No se gana nada metiendo esto en un procedimiento almacenado en lugar de construir esa misma sentencia en el lado cliente.

    • Propuesto como respuesta Carlos Aldi viernes, 6 de julio de 2018 16:01
    • Marcado como respuesta Pablo Rubio lunes, 8 de octubre de 2018 15:25
    viernes, 6 de julio de 2018 15:52
  • La N por delante de una cadena entre comillas dice que esa cadena es Nvarchar en lugar de ser Varchar. No pasa nada si la omites, el varchar se convierte implícitamente en nvarchar si es necesario.

    Si tienes que pasar los nombres de los campos, el principio de operación es el mismo: los vas concatenando en la variable que yo he llamado @sql hasta que el resultado de concatenarlo todo resulter ser la sentencia Insert que querías ejecutar, y entonces la ejecutas con sp_exectesql.

    Pero insisto en que no merece la pena hacer esto en un procedimiento almacenado. Si vas a andar generando sql dinámico para luego ejecutar la sentencia resultante, para eso puedes hacerlo directamente en el código cliente, no se gana nada trasladando esa operación a un procedimiento almacenado. Los procedimientos almacenados tienen ciertas ventajas, pero todas esas ventajas se pierden en el momento en el que tienes que recurrir a meter sql dinámico dentro del procedimiento.

    • Marcado como respuesta Pablo Rubio lunes, 8 de octubre de 2018 15:25
    viernes, 6 de julio de 2018 16:38

Todas las respuestas

  • Es algo bastante "feo" porque las sentencias SQL no permiten parametrizar el nombre de la tabla, asi que hay que concatenarlo todo en un string y luego mandarlo ejecutar. Esto, aparte de ser poco eficiente porque no se guarda pre-optimizado, tiene el riesgo de que es sensible a los ataques de inyeccion de SQL, asi que tienes que cerciorarte de que has validado previamente los datos que se le pasan al procedimiento.

    Dicho eso, el codigo que habria que meter en el procedimiento es mas o menos asi:

    declare @sql nvarchar(1000)
    set @sql = N'Insert into ' + @tabla + '(Id, Descripcion) Values(' + cast(Id as varchar) + ',' + '''' + descripcion + ''')'
    exec sp_executesql @sql
    

    Admite muchas optimizaciones, por ejemplo, el Id y la descripcion se podrian parametrizar dentro del sp_exeutesql. Aparte de eso, lo he escrito de memoria sin probarlo y es facil que contenga algun errorcilo que tendrias que corregir.

    Pero dicho eso, la cuestion es por que quieres hacer esto dentro de un procedimiento almacenado, dado que al tener que usar sql dinamico se pierden todas las ventajas de los procedimientos almacenados. No se gana nada metiendo esto en un procedimiento almacenado en lugar de construir esa misma sentencia en el lado cliente.

    • Propuesto como respuesta Carlos Aldi viernes, 6 de julio de 2018 16:01
    • Marcado como respuesta Pablo Rubio lunes, 8 de octubre de 2018 15:25
    viernes, 6 de julio de 2018 15:52
  • El detalle que también tengo que pasar como parámetro el id y descripcion de la campo de la tabla por que se llaman distinto en las diferentes tablas

    No entiendo que función hace la N la que esta antes de la sentencia INSERT

    viernes, 6 de julio de 2018 16:04
  • La N por delante de una cadena entre comillas dice que esa cadena es Nvarchar en lugar de ser Varchar. No pasa nada si la omites, el varchar se convierte implícitamente en nvarchar si es necesario.

    Si tienes que pasar los nombres de los campos, el principio de operación es el mismo: los vas concatenando en la variable que yo he llamado @sql hasta que el resultado de concatenarlo todo resulter ser la sentencia Insert que querías ejecutar, y entonces la ejecutas con sp_exectesql.

    Pero insisto en que no merece la pena hacer esto en un procedimiento almacenado. Si vas a andar generando sql dinámico para luego ejecutar la sentencia resultante, para eso puedes hacerlo directamente en el código cliente, no se gana nada trasladando esa operación a un procedimiento almacenado. Los procedimientos almacenados tienen ciertas ventajas, pero todas esas ventajas se pierden en el momento en el que tienes que recurrir a meter sql dinámico dentro del procedimiento.

    • Marcado como respuesta Pablo Rubio lunes, 8 de octubre de 2018 15:25
    viernes, 6 de julio de 2018 16:38