Sql server sql server动态查询中如何检查为空
我使用动态查询完成了以下存储过程,请参见下面的代码蓝图Sql server sql server动态查询中如何检查为空,sql-server,dynamic,dynamic-sql,isnull,Sql Server,Dynamic,Dynamic Sql,Isnull,我使用动态查询完成了以下存储过程,请参见下面的代码蓝图 ALTER PROCEDURE [dbo].[usp_Report] ( @LocationId INT = NULL ,@UserId INT = NULL) 声明@miscquery NVARCHAR(最大值); 开始 SET@miscquery= SELECT ,A.AgreementNumber AS Contract
ALTER PROCEDURE [dbo].[usp_Report] (
@LocationId INT = NULL
,@UserId INT = NULL)
声明@miscquery NVARCHAR(最大值);
开始
SET@miscquery=
SELECT
,A.AgreementNumber AS Contract
,A.AgreementId
FROM tblAgreement A
WHERE
AND (A.IsDeleted = 0 or A.IsDeleted is null)
AND (
(
' + convert(NVARCHAR(30), @LocationId) + ' IS NULL
AND (
A.CheckoutLocation IN (
SELECT LocationId
FROM [dbo].[tblUserLocations]
WHERE UserID = ' + convert(VARCHAR(10), @userId) +'
AND IsDeleted = 0
)
OR A.CheckoutLocation IS NULL
)
)
OR A.CheckoutLocation = ' + convert(VARCHAR(10), @LocationId) +'
)'
EXEC (@miscquery)
end
)
这里,当我执行@Locationid为null的查询时,结果不返回表,它返回如下
(63行受影响)
(受影响的2325行)
请帮帮我。谢谢您的代码不能是您的实际代码,首先是因为在声明之前,您一开始就试图设置一个名为
@miscquery
的变量。这段代码也没有理由是动态的,所以很明显你也在做一些其他的事情
出于某种原因,我将其视为您“需要”动态SQL。我将在标准警告中加入关于对输入进行消毒的内容。就这样
嗯。即使声明了@miscquery
,编写的代码也不会产生任何结果。它将抛出语法错误,或不执行任何操作,具体取决于您的设置
让我们举一个可能的例子:您有这个的默认设置,这意味着当您将varchar连接到null
时,结果是null
遵守以下代码:
declare @locationId int = null;
select 'this sentence ends with...' + convert(nvarchar(30), @locationId);
输出是什么
null
null
。当将null
值转换为字符串时,不会得到值为“null”的字符串,而是得到null
值
好的,现在我们尝试将null
添加到字符串的末尾。当您尝试使用+
运算符将null
值连接到字符串时,整个结果是null
因此,整个@miscquery
变量在赋值结束时为null
因此,您接下来所做的与此相同:
declare @myquery varchar(max) = null;
exec sp_executesql @myquery
这是有效的,不会抛出任何错误,但不会执行任何操作。然后,代码的其余部分执行它所执行的任何操作,并生成您看到的结果
如果将concat\u null\u yields\u null
设置为off,则会出现语法错误,因为当您将结果文本交给sp\u executesql
时,它将不是有效的SQL
正如Dan所说,最好和最安全的解决方案是参数化您的输入。但抛开这一点不谈,您需要的解决方案如下所示。在iif()
函数中,我查看@locationId
的值。如果它是null
,那么我想要字符串“null”。如果它不是null
,那么我需要对它的任何值进行字符串转换
declare @locationId int = null;
declare @query varchar(max) =
'select * from mytable where '
+ iif(@locationId is null, 'null', convert(nvarchar(30), @locationId))
+ ' is null';
print @query;
使用参数化查询,而不是使用串联构建SQL语句。这将解决空问题并提供其他好处。变量@userId
和@LocationId
来自哪里?它们不是参数,也不是声明的。@DanGuzman是对的,它甚至不需要是动态语句(更不用说参数化语句了)。使用parametrise语句并处理NULL
值。如果这是一个全面的查询,那么很可能值得向查询中添加选项(重新编译)
,这样就不会为不同的运行缓存糟糕的计划。嗨,如何编写Paramertize查询以检查是否为空,你能给出示例代码吗,我编辑了代码,请查看我在iif条件以上尝试的代码,但是,如果得到相同的输出,您可能会将其放在动态sql中,而不是使用它来构造动态sql。请编辑您的答案,以包含您的实际过程代码(您当前拥有的代码在语法上仍然无效,因此不能是您的真实代码),我将用您需要的确切代码更新我的答案。