Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server sql server动态查询中如何检查为空_Sql Server_Dynamic_Dynamic Sql_Isnull - Fatal编程技术网

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
  • 答案是3。注意:这不是一个值为“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。请编辑您的答案,以包含您的实际过程代码(您当前拥有的代码在语法上仍然无效,因此不能是您的真实代码),我将用您需要的确切代码更新我的答案。