Reputation: 1316
I am executing a dynamic SQL query. where parameters are passed dynamically. I first wrote similar to following code.
DECLARE @Id nvarchar(max);
DECLARE @query nvarchar(max);
SET @Id ='RMH_108'
SET @query ='Select *
FROM [A06].[Syn_RMDemand]
WHERE RMHierarchyId =' + @Id
PRINT @query
EXEC(@query)
Then I wrote this.
DECLARE @Id nvarchar(max);
DECLARE @query nvarchar(max);
SET @Id ='RMH_108'
SET @query ='Select *
FROM [A06].[Syn_RMDemand]
WHERE RMHierarchyId = '''+@Id+''''
PRINT @query
EXEC(@query)
This time code successfully executed. Since parameter can be empty I need to convert that to null. I modified the code and wrote this
DECLARE @Id nvarchar(max);
DECLARE @query nvarchar(max);
SET @Id = ''
SET @Id = NULLIF(@Id,'')
-- COMMENTED SET @Id ='RMH_108'
SET @query ='Select * FROM [A06].[Syn_RMDemand]
WHERE RMHierarchyId = '''+@Id+''''
PRINT @query
EXEC(@query)
No errors. Query crashed.
Does anybody come up with this sort of problem ?
Upvotes: 10
Views: 13431
Reputation: 1325
Anything with the arithmetic of NULL will yield NULL.
I'd do this way if NULL is meant for returning all rows:
SET @query ='Select * FROM [A06].[Syn_RMDemand]' +
case when @Id is not null then
' WHERE RMHierarchyId = ''' + @Id + '''' else '' end
And this way if to really want to have rows with NULL condition:
SET @query ='Select * FROM [A06].[Syn_RMDemand]
WHERE RMHierarchyId ' + case when @Id is null
then 'is NULL' else '= ''' + @Id +'''' end
But then again, it would always be better to avoid dynamic query at all cost. Consider:
Select * FROM [A06].[Syn_RMDemand] WHERE
(RMHierarchyId = @Id or nullif(@Id, '') is null)
And:
Select * FROM [A06].[Syn_RMDemand] WHERE (RMHierarchyId = @Id or
(RMHierarchyId is null and @Id is null))
Upvotes: 3
Reputation: 21931
try this
SET @query = 'Select * FROM [A06].[Syn_RMDemand] WHERE RMHierarchyId=''' + isnull(Convert(VARCHAR, @id), '') + ''' '
EXEC (@query)
Upvotes: 1
Reputation: 4958
No need to convert it to NULL just check with your value
DECLARE @Id nvarchar(max);
DECLARE @query nvarchar(max);
SET @Id = ''
-- COMMENTED SET @Id ='RMH_108'
SET @query ='Select * FROM [A06].[Syn_RMDemand]
WHERE RMHierarchyId = '''+@Id+''''
PRINT @query
EXEC(@query)
Upvotes: 1
Reputation: 5733
I am curious why no one suggesting there is no need to use dynamic SQL here
Select *
FROM [A06].[Syn_RMDemand]
WHERE NULLIF(@Id, '') IS NULL OR RMHierarchyId = @Id
Upvotes: 0
Reputation: 35780
Try the following:
SET @query ='Select * FROM [A06].[Syn_RMDemand]'
IF @Id IS NOT NULL
SET @query = @query + ' WHERE RMHierarchyId = '''+@Id+''''
If the parameter comes from client you better do with parametrized query(see @ughai's answer) in order to exclude sql injection
possibility...
Upvotes: 3
Reputation: 10264
You can also write as:
SET @query ='Select * FROM [A06].[Syn_RMDemand]
WHERE 1 = case when '''+@Id+''' = '''' then 1 when RMHierarchyId =
'''+@Id+''' then 1 else 0 end '
Upvotes: 0
Reputation: 31879
DECLARE @Id nvarchar(max);
DECLARE @query nvarchar(max);
SET @query = N'SELECT * FROM [A06].[Syn_RMDemand] ' + CHAR(10)
IF @Id IS NOT NULL BEGIN
SET @query = @query + N'WHERE RMHierarchyId = @param_id'
END
ELSE BEGIN
SET @query = @query + N'WHERE RMHierarchyId IS NULL'
END
PRINT @query
EXEC sp_executesql
@statement = @query,
@params = N'@param_id VARCHAR(MAX)',
@param_id = @Id
You should used parameterized query when using dynamic sql to avoid SQL Injection. Read this for more information.
If you want to return all rows if the @Id
passed is NULL
, just remove the ELSE
part.
Upvotes: 0
Reputation: 9880
You should use sp_executeSQL
and remove string concatenation like this. I am assuming that if NULL
is passed you want all the rows to be returned.
Query
DECLARE @Id nvarchar(max);
DECLARE @query nvarchar(max);
SET @Id ='RMH_108'SET @query ='Select *
FROM [A06].[Syn_RMDemand]
WHERE RMHierarchyId = @Id OR @ID IS NULL'
PRINT @query
EXEC sp_executeSQL @query,N'@Id NVARCHAR(MAX)',@Id
Upvotes: 4
Reputation: 10694
Try this.
SET @query ='Select * FROM [A06].[Syn_RMDemand]
WHERE RMHierarchyId = ' + ISNULL( @Id , '')
Upvotes: 1