如何在 sql 服务器的动态查询中检查 IS NULL
How to check IS NULL in dynamic query in sql server
我使用动态查询做了以下存储过程,请参见以下代码蓝图
ALTER PROCEDURE [dbo].[usp_Report] (
@LocationId INT = NULL
,@UserId INT = NULL)
声明@miscquery NVARCHAR (MAX);
开始
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 执行查询时,结果不是 return table,它 return 如下所示
(63 行受影响)
(2325 行受影响)
请帮帮我。谢谢
您拥有的代码不可能是您的实际代码,首先是因为在开始时您尝试在声明它之前设置一个名为 @miscquery
的变量。这段代码也没有理由是动态的,所以很明显你也在做一些其他的事情。
出于某种原因,我认为您“需要”动态 SQL。我将放入有关清理您的输入的标准警告。就是这样。
好的。即使声明了 @miscquery
,编写的代码也不会产生任何结果。根据您对 concat_null_yields_null
.
的设置,它要么抛出语法错误,要么什么都不做。
让我们以可能的情况为例:您对此有默认设置,这意味着当您将 varchar 连接到 null
时,结果是 null
.
遵守以下代码:
declare @locationId int = null;
select 'this sentence ends with...' + convert(nvarchar(30), @locationId);
输出结果是什么?
- “这句话结尾是……null”
- “这句话以...结尾”
null
答案是 3。请注意:这不是值为“null”的字符串。那只是 null
。当您将 convert
的 null
值赋给一个字符串时,您不会得到值为“null”的字符串,您会得到 null
值。
好的,现在我们尝试将 null
添加到字符串的末尾。当您尝试使用 +
运算符将 null
值连接到字符串时,整个结果为 null
.
因此,您的整个 @miscquery
变量在赋值结束时是 null
。
所以你现在所做的与此相同:
declare @myquery varchar(max) = null;
exec sp_executesql @myquery
这是有效的,不会抛出任何错误,但什么也不做。然后你的代码的其余部分做它做的任何事情,并产生你看到的结果。
如果 concat_null_yields_null
被设置为关闭那么你会得到一个语法错误,因为当你把它交给 sp_executesql
.[=36 时生成的文本将是无效的 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;
我使用动态查询做了以下存储过程,请参见以下代码蓝图
ALTER PROCEDURE [dbo].[usp_Report] (
@LocationId INT = NULL
,@UserId INT = NULL)
声明@miscquery NVARCHAR (MAX); 开始 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 执行查询时,结果不是 return table,它 return 如下所示
(63 行受影响)
(2325 行受影响)
请帮帮我。谢谢
您拥有的代码不可能是您的实际代码,首先是因为在开始时您尝试在声明它之前设置一个名为 @miscquery
的变量。这段代码也没有理由是动态的,所以很明显你也在做一些其他的事情。
出于某种原因,我认为您“需要”动态 SQL。我将放入有关清理您的输入的标准警告。就是这样。
好的。即使声明了 @miscquery
,编写的代码也不会产生任何结果。根据您对 concat_null_yields_null
.
让我们以可能的情况为例:您对此有默认设置,这意味着当您将 varchar 连接到 null
时,结果是 null
.
遵守以下代码:
declare @locationId int = null;
select 'this sentence ends with...' + convert(nvarchar(30), @locationId);
输出结果是什么?
- “这句话结尾是……null”
- “这句话以...结尾”
null
答案是 3。请注意:这不是值为“null”的字符串。那只是 null
。当您将 convert
的 null
值赋给一个字符串时,您不会得到值为“null”的字符串,您会得到 null
值。
好的,现在我们尝试将 null
添加到字符串的末尾。当您尝试使用 +
运算符将 null
值连接到字符串时,整个结果为 null
.
因此,您的整个 @miscquery
变量在赋值结束时是 null
。
所以你现在所做的与此相同:
declare @myquery varchar(max) = null;
exec sp_executesql @myquery
这是有效的,不会抛出任何错误,但什么也不做。然后你的代码的其余部分做它做的任何事情,并产生你看到的结果。
如果 concat_null_yields_null
被设置为关闭那么你会得到一个语法错误,因为当你把它交给 sp_executesql
.[=36 时生成的文本将是无效的 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;