Bu benzer sorunun cevabına buradan bakmak isteyebilirsiniz:
/programming/11329823/add-where-clauses-to-sql-dynamically-programmatically
Bir grup isteğe bağlı parametreyi alan ve filtreyi şu şekilde uygulayan bir SPROC'un:
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)
çalıştırıldığı ilk yürütme planını önbelleğe alır (örn. @optionalParam1 = 'Hello World', @optionalParam2 = NULL
), ancak farklı bir dizi isteğe bağlı parametre (örn. @optionalParam1 = NULL, @optionalParam2 = 42
) iletirsek sefil performans gösterir . (Ve tabii ki önbelleğe alınmış planın performansını istiyoruz, bu yüzden WITH RECOMPILE
çıktı)
Buradaki istisna, isteğe bağlı parametrelere ek olarak, sorgu üzerinde YÜKSEK seçici ve düzgün bir şekilde indekslenmiş en az bir ZORUNLU filtre varsa, yukarıdaki PROC'nin iyi performans göstermesidir.
Bununla birlikte, TÜM filtreler isteğe bağlıysa, oldukça korkunç gerçek, parametrelenmiş dinamik sql'nin daha iyi performans göstermesidir (isteğe bağlı parametrelerin her permütasyonu için N! Farklı statik PROCS yazmazsanız).
Aşağıdaki gibi dinamik SQL, Sorgu parametrelerinin her bir permütasyonu için farklı bir plan oluşturur ve önbelleğe alır, ancak en azından her plan belirli bir sorguya 'uyarlanır' (bir PROC veya Adhoc SQL olup olmadığı önemli değildir) parametrelenmiş sorgular oldukları sürece önbelleğe alınırlar)
Bu yüzden benim tercihim:
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
Yedek parametrelerde sp_executesql'e geçersek önemli değil - yok sayılırlar. ORM'lerin Linq2SQL ve EF gibi parametreli dinamik sql'i benzer şekilde kullandığını belirtmek gerekir.