I need to create a stored procedure which takes 12 arguments and the query is filtered with a different combination of this arguments. All 12 arguments are not mandatory as if I pass 3 or 5 or 12 arguments depends on search inputs entered by user.
I can create 2 ways, either using a dynamic SQL query or using ‘Case where’ statements. Example of these queries are as below:
-
Dynamic Query
DECLARE @sql VARCHAR(MAX) DECLARE @condition VARCHAR(MAX)='' Declare @var1 varchar(10) Declare @var2 varchar(10) Declare @var3 varchar(10) SET @sql='SELECT * FROM TableDemo1 TD1 WITH(NOLOCK) INNER JOIN TableDemo2 TD2 ON TD1.Column1=TD2.Column2' if(@var1 <>0 and @var1 is not null) begin if(@condition<>'') begin set @condition=@condition + ' and TD1.columnTest1='+@var1) end else begin set @condition=' where TD1.columnTest1='+@var1 end end if(@var2 <>0 and @var2 is not null) begin if(@condition<>'') begin set @condition=@condition + ' and TD2.columnTest2='+@var2) end else begin set @condition=' where TD2.columnTest2='+@var2 end end if(@var3 <>0 and @var3 is not null) begin if(@condition<>'') begin set @condition=@condition + ' and TD1.columnTest3='+@var3) end else begin set @condition=' where TD1.columnTest3='+@var3 end end SET @sql=@sql+@condition EXEC(@sql) -
Query with CASE WHERE
Declare @var1 varchar(10) Declare @var2 varchar(10) Declare @var3 varchar(10) SELECT * FROM TableDemo1 TD1 WITH(NOLOCK) INNER JOIN TableDemo2 TD2 ON TD1.Column1=TD2.Column2 WHERE (CASE WHEN (@var1<>0 and @var1 is not null) THEN CASE WHEN TD1.columnTest1=@var1 THEN 1 ELSE 0 END ELSE 1 END)=1 AND (CASE WHEN (@var2<>0 and @var2 is not null) THEN CASE WHEN TD2.columnTest2=@var2 THEN 1 ELSE 0 END ELSE 1 END)=1 AND (CASE WHEN (@var3<>0 AND @var3 IS NOT NULL) THEN CASE WHEN TD1.columnTest3 = @var3 THEN 1 ELSE 0 END ELSE 1 END) =1
This is just part of my stored procedure, there are 7-8 tables with joins and as above in query variety in conditions.
If I use a dynamic query, SQL Server will have to create an execution plan every time, but if I use ‘case where’ it also makes the query slow.
I am aware of disadvantages of dynamic SQL, but which technique I should use?
Generally it depends, but most often I use dynamic queries as a last resort. Regarding your question, I would most probably go with the CASE solution, but I think your CASE expressions are unnecessarily complicated. I would replace the WHERE clause with something like this:
With proper indexing this shouldn’t be too slow.