Reputation: 2499
I have a stored procedure that uses dynamic SQL. My company recently decided to get rid of dynamic code.
Here I greatly simplified it to explain my point; @PersonID
and @MhnNum
are parameters of the stored procedure:
Declare @sql Varchar(max)
Set @sql="Select from tableA p"
If @PersonID Is Not Null
Set @sql = @sql + ' Where p.[ID] = ' + cast(@PersonID as varchar(12))
If @MhnNum Is Not Null
Set @sql = @sql + ' Where p.[MhnNum] = ' + '''' + cast(@MhnNum as varchar(12)) + ''''
Is there an (easy) way to get rid of this dynamic SQL?
Right now my solution is to create 2 If's with repetitive code. There must be a more elegant way to do this.
Upvotes: 0
Views: 207
Reputation: 95588
Honestly, Dynamic SQL is probably the way to go, as you have a catch-all query, just not your dynamic SQL. It's a huge injection risk. Parametrise the statements:
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = CHAR(13) + CHAR(10);
SET @SQL = N'SELECT *' + @CRLF +
N'FROM TableA A' + @CRLF +
CASE WHEN @PersonID IS NOT NULL THEN N'WHERE A.ID = @PersonID;'
WHEN @MhnNum IS NOT NULL THEN N'WHERE A.MhnNum = @MhnNum;'
END;
EXEC sys.sp_executesql @SQL, N'@PersonID int, @MhnNum int', @PersonID, @MhnNum;
Using a non-dynamic approach will cause the caching of bad query plans, which isn't going to be desired.
If you must use non dynamic SQL (due to a pointless Company Policy, there is nothing wrong with Dynamic SQL if used correctly), then add OPTION RECOMPILE
:
IF @PersonID IS NOT NULL AND @MhnNum IS NOT NULL
THROW 68542, N'Both @PersonID and @MhnNum cannot be non-NULL values.', 11;
SELECT *
FROM TableA A
WHERE (A.ID = @PersonID OR @PersonID IS NULL)
AND (A.MhnNum = @MhnNum OR @MhnNum IS NULL)
OPTION (RECOMPILE);
The THROW
is in there, as your code will also error if you have 2 non-NULL
values.
Upvotes: 4
Reputation: 82474
A simple combination of or
and and
can get you the same result:
Select *
From tableA
Where (@personId is null or id = @personId)
And (@MhnNum is null or whnNum =@mhnNum)
Upvotes: 2
Reputation: 23797
(writing in a comment would be a mess)
You could check the parameters and act accordingly. ie:
Select from tableA p
where (@PersonID IS NULL or p.[ID] = @PersonID) and
(@MhnNum IS NULL or p.[MhnNum] = @MhnNum);
Upvotes: 1