【问题标题】:Dynamic WHERE condition SQL SERVER动态 WHERE 条件 SQL SERVER
【发布时间】:2020-10-13 18:52:39
【问题描述】:

我有以下要求。当 FirstName 存在时,我应该返回唯一的 condtionFirstName 当 LastName 存在时,我应该返回唯一的 condtionlastName 当 First 和 email 都存在时,我应该返回 condtionFirstName + condtionEmail。

基本上,无论存在哪个值,我都应该返回该条件,如果 1 值 1 条件,如果 1 和 2 则条件 1 和 2,如果 1 和 3 则条件 1 和 3,如果只有 3 则条件 3。

请帮我理解这个逻辑。

DECLARE @FirstName      NVARCHAR(100)
DECLARE @LastName       NVARCHAR(100)
DECLARE @Email          NVARCHAR(200)
DECLARE @condtionFirstName NVARCHAR(200)
DECLARE @condtionlastName NVARCHAR(200)
DECLARE @condtionEmail NVARCHAR(200)

SET @FirstName = 'JOhn'
SET @LastName  = 'David'
SET @Email     = 'john.david@abc.com'

SET @condtionFirstName = ' AND FirstName = ' + '''' + @FirstName + ''''  
SET @condtionlastName =  ' AND LastName = ' + '''' + @LastName + ''''
SET @condtionEmail = ' AND Email = ' + '''' + @Email + ''''

【问题讨论】:

标签: sql-server sql-server-2012 sql-server-2014


【解决方案1】:

这就是我长期以来所说的“the kitchen sink”——您需要一个可以支持任意搜索条件组合的查询。一些想法:

  • 停止尝试将用户输入与可执行字符串连接 - 这是危险且容易出错的。这些应始终作为显式类型的参数传入。
  • 您可以构建包含所有条件的单个字符串,而不是尝试为每个可能的条件创建一个新的条件字符串。
  • 您可以声明参数并将其传递给sp_executesql,即使它们并未全部出现在动态SQL 语句中。这就像声明一个局部变量而不使用它一样。
  • 电子邮件地址的长度可以为 320 个字符。如果你只支持 200 个,那可能会咬你一口。

示例:

DECLARE @FirstName         nvarchar(100),
        @LastName          nvarchar(100),
        @Email             nvarchar(320),
        @conditions        nvarchar(max) = N'';

SET @FirstName = N'John';
SET @LastName  = N'David';
SET @Email     = N'john.david@abc.com';

SET @conditions += CASE WHEN @FirstName IS NOT NULL THEN
      N' AND FirstName = @FirstName' ELSE N'' END
  + CASE WHEN @LastName IS NOT NULL THEN
      N' AND LastName = @LastName' ELSE N'' END
  + CASE WHEN @Email IS NOT NULL THEN
      N' AND Email = @Email' ELSE N'' END;

DECLARE @sql nvarchar(max) = N'SELECT ... FROM dbo.table 
        WHERE 1 = 1' + @conditions;

PRINT @sql; -- try this when populating or not populating each of
            -- @FirstName, @LastName, @Email

EXEC sys.sp_executesql @sql, 
  N'@FirstName nvarchar(100), @LastName nvarchar(100), @Email nvarchar(320)', 
  @FirstName, @LastName, @Email;

更多细节:

【讨论】:

  • 感谢@Aaron Bertrand 的意见。如果我的姓氏中有空白或空值,那么我不应该有这种情况。我应该只有另外两个条件。
  • @NaveenKumar 是的,你试过了吗? PRINT @sql; 而不是 EXEC。也不要把'' 和NULL 说成同一个意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-30
  • 2014-09-30
相关资源
最近更新 更多