将空值参数传递给动态SQL查询。如何才能成功地执行此操作?
我正在执行一个动态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)
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))