首页 > 解决方案 > 动态 WHERE 条件 SQL SERVER

问题描述

我有以下要求。当 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-serversql-server-2012sql-server-2014

解决方案


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

  • 停止尝试将用户输入与可执行字符串连接 - 这是危险且容易出错的。这些应该始终作为显式类型的参数传入。
  • 您可以构建一个包含所有条件的字符串,而不是尝试为每个可能的条件创建一个新的条件字符串。
  • 您可以声明和传递参数,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;

更多细节:


推荐阅读