Modifica - Preferenze per LINQ basa ORM, se possibile
Se non è necessario eseguire questa operazione in ADO, una soluzione migliore consiste nell'utilizzare un ORM che alla fine creerà paramete ralizzato ad-hoc sql. Questo è il meglio di entrambi i mondi: si ottiene la flessibilità di una query dinamica, senza filtri ridondanti per sconvolgere l'ottimizzatore, il piano di query stesso è memorizzabile nella cache e si è al sicuro da virus come attacchi di iniezione. E una query ORM Linq-based rende per una facile lettura:
// 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();
Per le query complesse, si consiglia di guardare PredicateBuilder
ADO edificio/manuale di query
È possibile utilizzare sp_executesql
per creare SQL in modo dinamico come di seguito. A condizione di parametrizzare le variabili che dovrebbero essere al sicuro da problemi come l'iniezione SQL e le citazioni di escape ecc. Saranno gestite per te.
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, perché è WHERE (@x IS NULL OR @x = Column)
una cattiva idea?
(Dal mio commento qui sotto)
Anche se il modello 'parametro opzionale' funziona bene come un 'coltellino svizzero' per interrogare un gran numero di permutazioni di filtri opzionali quando viene utilizzato su piccoli tavoli, purtroppo, per i grandi tabelle, questo si traduce in un piano di query singolo per tutte le permutazioni dei filtri per la query, che può comportare prestazioni di query scadenti con determinate permutazioni di parametri opzionali a causa dello parameter sniffing problem. Se possibile, è necessario eliminare completamente i filtri ridondanti.
Re: Perché l'applicazione funzioni in predicati una cattiva idea
esempio
WHERE SomeFunction(Column) = @someParameter
Uso di funzioni in predicati squalifica spesso l'uso di indici dall'RDBMS ("non-sargable").
In questo caso, RTRIM
non è necessario come server Sql ignores spazi finali during comparison.
Possibile duplicato: http://stackoverflow.com/questions/977021/can-a-stored-procedure-have-dynamic-parameters-to-be-used-in-an-in-clause – phadaphunk