Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

[SOLUCIONADO] Sql server dinámico

Estas en el tema de Sql server dinámico en el foro de SQL Server en Foros del Web. Señores, de antemano gracias por la ayuda que me puedan brindar. Soy nuevo en el foro y mi consulta es la siguiente, estoy creando una ...
  #1 (permalink)  
Antiguo 27/11/2013, 13:48
 
Fecha de Ingreso: noviembre-2013
Mensajes: 5
Antigüedad: 10 años, 5 meses
Puntos: 0
Sql server dinámico

Señores, de antemano gracias por la ayuda que me puedan brindar. Soy nuevo en el foro y mi consulta es la siguiente, estoy creando una query dinámicamente en un procedimiento, a continuación dejo el código:

Código SQL:
Ver original
  1. ALTER PROCEDURE [dbo].[SEL_USUARIO_BY_SEARCH] @Departamento NVARCHAR(50), @Usuario NVARCHAR(50),
  2. @Nombre NVARCHAR(128) AS
  3.     DECLARE @SQL NVARCHAR(4000)
  4.     SET @SQL = 'SELECT U.IdUsuario, U.Departamento, D.NombreDepartamento, U.NickUsuario, U.ContrasegnaUsuario,
  5.         U.NombresUsuario + '' '' + U.PrimerApellidoUsuario + '' '' + U.SegundoApellidoUsuario Usuario,
  6.         U.EmailUsuario, U.TelefonoUsuario, CONVERT(VARCHAR, U.FechaIngresoUsuario, 103) FechaIngreso,
  7.         CONVERT(VARCHAR, U.UltimoIngresoUsuario, 103) UltimoIngreso, U.ImagenUsuario
  8.         FROM Usuarios U INNER JOIN Departamentos D ON U.Departamento = D.IdDepartamento
  9.         WHERE 1 = 1'
  10.     IF @Departamento IS NOT NULL AND @Departamento <> ''
  11.     BEGIN
  12.         SET @SQL = @SQL + ' AND (D.NombreDepartamento LIKE ''%\' + Quotename(@Departamento,'''') + '%'' ESCAPE ''\''
  13.         OR D.NombreDepartamento LIKE ''%_' + Quotename(@Departamento,'''') + '%'' ESCAPE ''_'')'
  14.     END
  15.     IF @Usuario IS NOT NULL AND @Usuario <> ''
  16.     BEGIN
  17.         SET @Sql = @Sql + ' AND (U.NickUsuario LIKE ''%\' + Quotename(@Usuario,'''') + '%'' ESCAPE ''\''
  18.         OR U.NickUsuario LIKE ''%_' + Quotename(@Usuario,'''') + '%'' ESCAPE ''_'')'
  19.     END
  20.     IF @Nombre IS NOT NULL AND @Nombre <> ''
  21.     BEGIN
  22.         SET @Sql = @Sql + ' AND (U.NombresUsuario' + ' ' + 'U.PrimerApellidoUsuario' + ' ' + 'U.SegundoApellidoUsuario LIKE ''%\' + Quotename(@Nombre,'''') + '%'' ESCAPE ''\''
  23.         OR U.NombresUsuario' + ' ' + 'U.PrimerApellidoUsuario' + ' ' + 'U.SegundoApellidoUsuario LIKE ''%_' + Quotename(@Nombre,'''') + '%'' ESCAPE ''_'')'
  24.     END
  25.     SET @Sql = @Sql + ' ORDER BY U.NickUsuario ASC'
  26.     BEGIN TRAN
  27.         PRINT @Sql
  28.         --EXEC(@Sql)
  29.     COMMIT TRAN
  30. END

Al ejecutar (por ejemplo EXEC SEL_USUARIO_BY_SEARCH 'P', 'r', 'r') el resultado es el siguiente:

Código SQL:
Ver original
  1. SELECT U.IdUsuario, U.Departamento, D.NombreDepartamento, U.NickUsuario, U.ContrasegnaUsuario,
  2. U.NombresUsuario + ' ' + U.PrimerApellidoUsuario + ' ' + U.SegundoApellidoUsuario Usuario,
  3. U.EmailUsuario, U.TelefonoUsuario, CONVERT(VARCHAR, U.FechaIngresoUsuario, 103) FechaIngreso,
  4. CONVERT(VARCHAR, U.UltimoIngresoUsuario, 103) UltimoIngreso, U.ImagenUsuario
  5. FROM Usuarios U INNER JOIN Departamentos D ON U.Departamento = D.IdDepartamento
  6. WHERE 1 = 1 AND (D.NombreDepartamento LIKE '%\'P'%' ESCAPE '\'
  7. OR D.NombreDepartamento LIKE '%_'P'%' ESCAPE '_') AND (U.NickUsuario LIKE '%\'r'%' ESCAPE '\'
  8. OR U.NickUsuario LIKE '%_'r'%' ESCAPE '_') AND (U.NombresUsuario U.PrimerApellidoUsuario U.SegundoApellidoUsuario LIKE '%\'r'%' ESCAPE '\'
  9. OR U.NombresUsuario U.PrimerApellidoUsuario U.SegundoApellidoUsuario LIKE '%_'r'%' ESCAPE '_') ORDER BY U.NickUsuario ASC

Se puede observar que la consulta es correcta, con la excepción de que los parámetros enviados quedan entre comillas, por lo cual nunca me dará resultado alguno.

Ojalá se pueda solucionar. Gracias.

Última edición por gnzsoloyo; 27/11/2013 a las 16:25
  #2 (permalink)  
Antiguo 27/11/2013, 14:04
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Sql server dinámico

pregunta para que es el ESCAPE??? y para que usas el quotename??

prueba con esto:

Código SQL:
Ver original
  1. ALTER PROCEDURE [dbo].[SEL_USUARIO_BY_SEARCH] @Departamento NVARCHAR(50), @Usuario NVARCHAR(50),
  2. @Nombre NVARCHAR(128) AS
  3. DECLARE @SQL NVARCHAR(4000)
  4. SET @SQL = 'SELECT U.IdUsuario, U.Departamento, D.NombreDepartamento, U.NickUsuario, U.ContrasegnaUsuario,
  5. U.NombresUsuario + '' '' + U.PrimerApellidoUsuario + '' '' + U.SegundoApellidoUsuario Usuario,
  6. U.EmailUsuario, U.TelefonoUsuario, CONVERT(VARCHAR, U.FechaIngresoUsuario, 103) FechaIngreso,
  7. CONVERT(VARCHAR, U.UltimoIngresoUsuario, 103) UltimoIngreso, U.ImagenUsuario
  8. FROM Usuarios U INNER JOIN Departamentos D ON U.Departamento = D.IdDepartamento
  9. WHERE 1 = 1'
  10. IF @Departamento IS NOT NULL AND @Departamento <> ''
  11. BEGIN
  12. SET @SQL = @SQL + ' AND (D.NombreDepartamento LIKE ''%\' + @Departamento + '%'' ESCAPE ''\''
  13. OR D.NombreDepartamento LIKE ''%_' + @Departamento + '%'' ESCAPE ''_'')'
  14. END
  15. IF @Usuario IS NOT NULL AND @Usuario <> ''
  16. BEGIN
  17. SET @Sql = @Sql + ' AND (U.NickUsuario LIKE ''%\' + @Usuario + '%'' ESCAPE ''\''
  18. OR U.NickUsuario LIKE ''%_' + @Usuario + '%'' ESCAPE ''_'')'
  19. END
  20. IF @Nombre IS NOT NULL AND @Nombre <> ''
  21. BEGIN
  22. SET @Sql = @Sql + ' AND (U.NombresUsuario' + ' ' + 'U.PrimerApellidoUsuario' + ' ' + 'U.SegundoApellidoUsuario LIKE ''%\' + @Nombre + '%'' ESCAPE ''\''
  23. OR U.NombresUsuario' + ' ' + 'U.PrimerApellidoUsuario' + ' ' + 'U.SegundoApellidoUsuario LIKE ''%_' + @Nombre + '%'' ESCAPE ''_'')'
  24. END
  25. SET @Sql = @Sql + ' ORDER BY U.NickUsuario ASC'
  26. BEGIN TRAN
  27. PRINT @Sql
  28. --EXEC(@Sql)
  29. COMMIT TRAN
  30. END
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 27/11/2013, 14:37
 
Fecha de Ingreso: noviembre-2013
Mensajes: 5
Antigüedad: 10 años, 5 meses
Puntos: 0
Respuesta: Sql server dinámico

Cita:
Iniciado por Libras Ver Mensaje
pregunta para que es el ESCAPE??? y para que usas el quotename??

prueba con esto:

Código SQL:
Ver original
  1. ALTER PROCEDURE [dbo].[SEL_USUARIO_BY_SEARCH] @Departamento NVARCHAR(50), @Usuario NVARCHAR(50),
  2. @Nombre NVARCHAR(128) AS
  3. DECLARE @SQL NVARCHAR(4000)
  4. SET @SQL = 'SELECT U.IdUsuario, U.Departamento, D.NombreDepartamento, U.NickUsuario, U.ContrasegnaUsuario,
  5. U.NombresUsuario + '' '' + U.PrimerApellidoUsuario + '' '' + U.SegundoApellidoUsuario Usuario,
  6. U.EmailUsuario, U.TelefonoUsuario, CONVERT(VARCHAR, U.FechaIngresoUsuario, 103) FechaIngreso,
  7. CONVERT(VARCHAR, U.UltimoIngresoUsuario, 103) UltimoIngreso, U.ImagenUsuario
  8. FROM Usuarios U INNER JOIN Departamentos D ON U.Departamento = D.IdDepartamento
  9. WHERE 1 = 1'
  10. IF @Departamento IS NOT NULL AND @Departamento <> ''
  11. BEGIN
  12. SET @SQL = @SQL + ' AND (D.NombreDepartamento LIKE ''%\' + @Departamento + '%'' ESCAPE ''\''
  13. OR D.NombreDepartamento LIKE ''%_' + @Departamento + '%'' ESCAPE ''_'')'
  14. END
  15. IF @Usuario IS NOT NULL AND @Usuario <> ''
  16. BEGIN
  17. SET @Sql = @Sql + ' AND (U.NickUsuario LIKE ''%\' + @Usuario + '%'' ESCAPE ''\''
  18. OR U.NickUsuario LIKE ''%_' + @Usuario + '%'' ESCAPE ''_'')'
  19. END
  20. IF @Nombre IS NOT NULL AND @Nombre <> ''
  21. BEGIN
  22. SET @Sql = @Sql + ' AND (U.NombresUsuario' + ' ' + 'U.PrimerApellidoUsuario' + ' ' + 'U.SegundoApellidoUsuario LIKE ''%\' + @Nombre + '%'' ESCAPE ''\''
  23. OR U.NombresUsuario' + ' ' + 'U.PrimerApellidoUsuario' + ' ' + 'U.SegundoApellidoUsuario LIKE ''%_' + @Nombre + '%'' ESCAPE ''_'')'
  24. END
  25. SET @Sql = @Sql + ' ORDER BY U.NickUsuario ASC'
  26. BEGIN TRAN
  27. PRINT @Sql
  28. --EXEC(@Sql)
  29. COMMIT TRAN
  30. END

Estimado, muchas gracias, funcionó perfecto. Efectivamente el problema estaba en Quotename el cual lo estaba utilizando para generación de comillas en una consulta anterior:

Código SQL:
Ver original
  1. DECLARE @SQL NVARCHAR(500)
  2.     SET @SQL = 'SELECT * FROM Usuarios WHERE 1 = 1'
  3.     IF @Usuario IS NOT NULL AND @Usuario <> ''
  4.     BEGIN
  5.         SET @SQL = @SQL + ' AND NickUsuario = ' + Quotename(@Usuario,'''') + ''
  6.     END
  7.     EXEC(@SQL)
al no colocar Quotename, si ejecuto EXEC Search 'pp', '' la consulta me devuelve SELECT * FROM Usuarios WHERE 1 = 1 AND NickUsuario = [pp]

El escape lo utilizo por motivos de seguridad http://mteheran.wordpress.com/2010/0...on-sql-server/ en ese link se explica el por qué.

Muchas gracias nuevamente Libras.

Última edición por gnzsoloyo; 27/11/2013 a las 16:26
  #4 (permalink)  
Antiguo 27/11/2013, 14:41
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Sql server dinámico

creo que la parte de escape seria mejor manejarla desde la aplicacion, desde ahi validar que lleguen los datos limpios, aunque nunca esta de mas una doble checada :P
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #5 (permalink)  
Antiguo 27/11/2013, 14:53
 
Fecha de Ingreso: noviembre-2013
Mensajes: 5
Antigüedad: 10 años, 5 meses
Puntos: 0
Respuesta: Sql server dinámico

Es justamente lo que hago siempre con todos los lenguajes y motores de bdd, no quedarme solamente con la chequeada de un solo lado, aunque parezca exagerado.
  #6 (permalink)  
Antiguo 27/11/2013, 15:07
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Sql server dinámico

muy buena practica, aunque creo que es demasiada paranoia :P jejejejeje
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Etiquetas: fecha, procedimiento, select, server, sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:36.