代码之家  ›  专栏  ›  技术社区  ›  Ahmy

SQL中字符串内的处理为空

  •  2
  • Ahmy  · 技术社区  · 14 年前

    我有一个SQL查询,它是用字符串编写的,然后使用命令Exec(string)执行,如下所示:

    Declare @TestId bigint = null
    Declare @Query nvarchar(max)
    set @Query = 'SELECT * from Registrations where RegistrationId = 15 AND (' + CAST(@TestId AS NVARCHAR) + ' IS NULL OR TestId = ' + CAST(@TestId AS NVARCHAR) + ') '
    EXEC(@Query)
    

    现在的问题是没有在字符串中正确地解析IS NULL,但是当我从字符串中删除IS NULL时,它会正常工作;当@TestId接受一个非NULL的值时,它会正常工作,现在的问题是在@Query字符串中强制转换IS NULL。

    :@TestId是一个过程参数

    我需要知道如何让SQL感觉为空并正确解析它

    5 回复  |  直到 14 年前
        1
  •  4
  •   AdaTheDev    14 年前

    如果确实需要为此使用动态sql,请像这样使用sp\u executesql:

    Declare @TestId bigint = null
    Declare @Query nvarchar(max)
    set @Query = 'SELECT * from Registrations where RegistrationId = 15 AND (@TestId IS NULL OR TestId = @TestId)'
    
    EXECUTE sp_executesql @Query, N'@TestId BIG INT', @TestId
    
        2
  •  1
  •   Martin Smith    14 年前

    您不需要使用动态SQL。另外,如果您要生成动态SQL,这样做的好处之一就是您的查询不需要有这种类型的SQL WHERE TestId =@TestId OR @TestId IS NULL

    Declare @TestId bigint = null
    Declare @Query nvarchar(max)
    
    IF @TestId IS NULL
    SELECT * from Registrations where RegistrationId = 15
    ELSE
    SELECT * from Registrations where RegistrationId = 15 AND TestId =@TestId
    

    编辑

    sp_executesql 并生成 不同的字符串 @TestId is null . 不要把两个案例都塞进同一个查询中。

        3
  •  1
  •   bobs    14 年前

    其他答案提供了解决方案。这就是为什么你的解决方案不起作用。当@TestId为null时,将null连接到@Query字符串,并将null分配给@Query。若您打印@Query来代替exec,您将看到将要运行的查询。

    Declare @TestId bigint = 10--null
    Declare @Query nvarchar(max)
    set @Query = 'SELECT * from Registrations where RegistrationId = 15 AND (' + CAST(@TestId AS NVARCHAR) + ' IS NULL OR TestId = ' + CAST(@TestId AS NVARCHAR) + ') '
    --EXEC(@Query)
    print @Query
    
        4
  •  0
  •   Justin Niessner    14 年前

    构建动态查询是不好的,m'kay…也就是说,您可以通过将null检查移到动态查询之外并在那里处理它来修复它:

    set @Query = 'select * from registrations where registrationId = 15 and
                 CAST(TestId AS NVARCHAR) = ' + ISNULL(CAST(@TestId AS NVARCHAR), '')
    

    select * from registrations where registrationId = 15 and TestId = @TestId
    
        5
  •  0
  •   Janick Bernet    14 年前

    从您的代码中,我怀疑您想要的是通过TestId过滤注册的结果,因为它不是空的。为什么不以编程的方式而不是在SQL查询中这样做呢?沿着这些思路(我的语法可能是错误的):

    Declare @TestId bigint = null
    Declare @Query nvarchar(max)
    if(@TestId IS NULL)  
       set @Query = 'SELECT * from Registrations where RegistrationId = 15'
    else
       set @Query = 'SELECT * from Registrations where RegistrationId = 15 AND (TestId = ' + CAST(@TestId AS NVARCHAR) + ') '
    EXEC(@Query)
    

    另外,justinniessner是对的,如果可能的话,应该避免使用动态SQL(这可以在没有动态SQL的情况下完成)。