Editar - Preferencia por LINQ basa ORM, si es posible
Si no necesita hacer esto en ADO, una mejor solución es usar un ORM que finalmente construirá el parámetro rizado ad-hoc sql. Esto es lo mejor de ambos mundos: obtienes la flexibilidad de una consulta dinámica, sin filtros redundantes para alterar el optimizador, el plan de consulta en sí es almacenable en caché y estás a salvo de desagradables ataques de inyección. Y una consulta ORM basado en LINQ hace para facilitar la lectura:
// Build up a non-materialized IQueryable<>
var usersQuery = db.Users;
if (!string.IsNullOrEmpty(userID))
{
usersQuery = usersQuery.Where(u => u.Name == userId);
}
// Of course, you wouldn't dream of storing passwords in cleartext.
if (!string.IsNullOrEmpty(anotherField))
{
usersQuery = usersQuery.Where(u => u.AnotherColumn == anotherField);
}
...
// Materialize (and execute) the query
var filteredUsers = usersQuery.ToList();
Para consultas complejas, es posible que desee ver en PredicateBuilder edificio/consulta manual de
ADO
Puede utilizar sp_executesql
a construir SQL dinámicamente como se muestra a continuación. Siempre que usted parametrice las variables, debe estar a salvo de problemas como la inyección de SQL y las comillas de escape, etc. que se manejarán por usted.
CREATE PROCEDURE [dbo].[PROC001]
@userID varchar(20),
@password varchar(20),
@optionalParam1 NVARCHAR(50) = NULL -- Other optional parameters
AS
BEGIN
SET NOCOUNT ON
DECLARE @SQL NVARCHAR(MAX)
-- Mandatory/Static part of the Query here.
-- Cleartext passwords are verboten, and RTRIM is redundant in filters
SET @SQL = N'SELECT * FROM tUsers WHERE Name = @userID AND PwdHash = @pwdHash'
IF @OptionalParam1 IS NOT NULL
BEGIN
SET @SQL = @SQL + N' AND AnotherField = @OptionalParam1'
END
EXEC sp_executesql @SQL,
N'@userID varchar(20),
@pwdHash varchar(20),
@optionalParam1 NVARCHAR(50)'
,@userID = @userID
,@pwdHash = @pwdHash
,@optionalParam1 = @optionalParam1
END
Re, ¿por qué es WHERE (@x IS NULL OR @x = Column)
una mala idea?
(de mi comentario a continuación)
Aunque el patrón 'parámetro opcional' funciona bien como una 'navaja suiza' para consultar una multitud de permutaciones de filtros opcionales cuando se utiliza en pequeñas mesas, por desgracia, para los grandes tablas, esto da como resultado un único plan de consulta para todas las permutaciones de filtros para la consulta, lo que puede dar como resultado un bajo rendimiento de consulta con ciertas permutaciones de parámetros opcionales debido al parameter sniffing problem. Si es posible, debe eliminar por completo los filtros redundantes.
Re: ¿Por qué es la aplicación de funciones en los predicados una mala idea
por ejemplo,
WHERE SomeFunction(Column) = @someParameter
Uso de funciones en predicados descalifica con frecuencia el uso de índices por el RDBMS ("non-sargable").
En este caso, RTRIM
es innecesario como servidor Sql ignores espacios finales during comparison.
Posible duplicado: http://stackoverflow.com/questions/977021/can-a-stored-procedure-have-dynamic-parameters-to-be-used-in-an-in-clause – phadaphunk