Vielleicht möchten Sie die Antwort auf diese ähnliche Frage hier suchen:
/programming/11329823/add-where-clauses-to-sql-dynamically-programmatically
Wir haben festgestellt, dass ein SPROC eine Reihe von optionalen Parametern aufnimmt und den Filter folgendermaßen implementiert:
CREATE PROC MyProc (@optionalParam1 NVARCHAR(50)=NULL, @optionalParam2 INT=NULL)
AS
...
SELECT field1, field2, ... FROM [Table]
WHERE
(@optionalParam1 IS NULL OR MyColumn1 = @optionalParam1)
AND (@optionalParam2 IS NULL OR MyColumn2 = @optionalParam2)
Zwischenspeichern des ersten Ausführungsplans, mit dem er ausgeführt wird (z. B. @optionalParam1 = 'Hello World', @optionalParam2 = NULL), dann jedoch miserabel, wenn ein anderer Satz optionaler Parameter übergeben wird (z @optionalParam1 = NULL, @optionalParam2 = 42. B. ). (Und natürlich wollen wir die Leistung des zwischengespeicherten Plans, also WITH RECOMPILEist es aus)
Die Ausnahme hier ist, dass, wenn AUCH mindestens ein OBLIGATORISCHER Filter in der Abfrage vorhanden ist, der HOCH selektiv und ordnungsgemäß indiziert ist, zusätzlich zu den optionalen Parametern, der obige PROC eine gute Leistung erbringt.
Wenn jedoch ALLE Filter optional sind, ist die Wahrheit ziemlich schrecklich, dass parametrisiertes dynamisches SQL tatsächlich eine bessere Leistung erbringt (es sei denn, Sie schreiben N! Unterschiedliche statische PROCS für jede Permutation optionaler Parameter).
Dynamisches SQL wie das folgende erstellt und speichert für jede Permutation der Abfrageparameter einen anderen Plan im Cache, aber mindestens jeder Plan wird auf die spezifische Abfrage zugeschnitten (es spielt keine Rolle, ob es sich um ein PROC - oder ein Ad - hoc - SQL handelt) solange es sich um parametrisierte Abfragen handelt, werden sie zwischengespeichert)
Daher meine Präferenz für:
DECLARE @SQL NVARCHAR(MAX)
-- Mandatory / Static part of the Query here
SET @SQL = N'SELECT * FROM [table] WHERE 1 = 1'
IF @OptionalParam1 IS NOT NULL
BEGIN
SET @SQL = @SQL + N' AND MyColumn1 = @optionalParam1'
END
IF @OptionalParam2 IS NOT NULL
BEGIN
SET @SQL = @SQL + N' AND MyColumn2 = @optionalParam2'
END
EXEC sp_executesql @SQL,
N'@optionalParam1 NVARCHAR(50),
@optionalParam2 INT'
,@optionalParam1 = @optionalParam1
,@optionalParam2 = @optionalParam2
usw. Es spielt keine Rolle, ob wir redundante Parameter an sp_executesql übergeben - sie werden ignoriert. Es ist erwähnenswert, dass ORMs wie Linq2SQL und EF in ähnlicher Weise parametrisiertes dynamisches SQL verwenden.