将空值参数传递给动态SQL查询。如何才能成功地执行此操作?

将空值参数传递给动态SQL查询。如何才能成功地执行此操作?,sql,sql-server,Sql,Sql Server,我正在执行一个动态SQL查询。其中参数是动态传递的。我首先编写了类似于以下代码的代码 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)

我正在执行一个动态SQL查询。其中参数是动态传递的。我首先编写了类似于以下代码的代码

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)

然后我写了这个

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)

这次代码成功执行。由于参数可以为空,我需要将其转换为null。我修改了代码并编写了这个

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)

没有错误。查询已崩溃。
有人会遇到这种问题吗?

尝试以下方法:

SET @query ='Select * FROM [A06].[Syn_RMDemand]'
IF @Id IS NOT NULL
   SET @query = @query + ' WHERE RMHierarchyId = '''+@Id+''''
如果参数来自客户端,您最好使用参数化查询(请参见@ughai的答案),以排除
sql注入的可能性…

试试这个

SET @query ='Select * FROM [A06].[Syn_RMDemand]
             WHERE RMHierarchyId = ' + ISNULL( @Id , '')

您应该使用
sp_executeSQL
并删除如下字符串连接。我假设如果传递了
NULL
,您希望返回所有行

查询

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
在使用动态sql时,应该使用参数化查询,以避免sql注入。阅读了解更多信息

如果要在传递的
@Id
NULL
时返回所有行,只需删除
ELSE
部分。

您也可以编写为:

SET @query ='Select * FROM [A06].[Syn_RMDemand]
             WHERE 1 = case when '''+@Id+''' = '''' then 1 when  RMHierarchyId =      
             '''+@Id+''' then 1 else 0 end '

我很好奇为什么没有人建议这里不需要使用动态SQL

Select * 
FROM [A06].[Syn_RMDemand]
WHERE NULLIF(@Id, '') IS NULL OR RMHierarchyId = @Id

无需将其转换为NULL,只需检查您的值即可

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)
试试这个

SET @query = 'Select * FROM [A06].[Syn_RMDemand] WHERE RMHierarchyId=''' + isnull(Convert(VARCHAR, @id), '') + ''' '

    EXEC (@query)

任何算术为NULL的运算都将产生NULL

如果NULL用于返回所有行,我会这样做:

SET @query ='Select * FROM [A06].[Syn_RMDemand]' +
            case when @Id is not null then 
            ' WHERE RMHierarchyId = ''' + @Id + '''' else '' end
这样,如果您真的希望有空条件的行:

SET @query ='Select * FROM [A06].[Syn_RMDemand]
             WHERE RMHierarchyId ' + case when @Id is null 
             then 'is NULL' else '= ''' + @Id +'''' end 
但话说回来,最好是不惜一切代价避免动态查询。考虑:

Select * FROM [A06].[Syn_RMDemand] WHERE  
             (RMHierarchyId = @Id or nullif(@Id, '') is null)
以及:


同样的结果。没有输出。@ArunprasanthKV它不工作。这是什么语法“(at)query”?其中一个有效值是
'RMH_108'
@Param
应该是
VARCHAR
/
NVARCHAR
而不是
@Param\u id integer
@Giogi Nakeuri。谢谢结果出来了,但我有个问题。如果我们有多个这样的参数会发生什么。我是否需要将每个参数都检查为空值?我认为,您应该建议使用
sp_executesql
作为参数,而不是使用Erland Sommarskog的字符串连接,这对您来说是一个很好的选择。请尝试以下设置@query='Select*FROM[A06].[Syn_RMDemand],其中RMHierarchyId=''+为空(Convert(VARCHAR,@id),'')+''EXEC(@query)谢谢@ArunprasanthKV..这很有效。谢谢。这也给出了结果。“任何使用NULL算法的东西都会产生NULL。”:人们可能会这么想,但我刚刚发现一个情况不是这样的:。
Select * FROM [A06].[Syn_RMDemand] WHERE  
             (RMHierarchyId = @Id or nullif(@Id, '') is null)
Select * FROM [A06].[Syn_RMDemand] WHERE (RMHierarchyId = @Id or
             (RMHierarchyId is null and @Id is null))