动态WHERE条件SQL SERVER

时间:2020-06-23 16:22:27

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

我有以下要求。当存在FirstName时,当LastName存在时,我应该返回唯一的condtionFirstName;当First和email都存在时,我应该返回唯一的condtionlastName;我应该返回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 + ''''

1 个答案:

答案 0 :(得分:3)

这就是我长期以来所说的“ 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;

更多详细信息: