【问题标题】:sql search query with multiple optional search parameters具有多个可选搜索参数的 sql 搜索查询
【发布时间】:2014-03-04 18:21:03
【问题描述】:

我在 sql 2008 中有一个查询,其中用户可以选择多个可选参数,如下所示:

@DateFrom
@DateTo
@UserType
@Customer
@User

基于所有这些选项的最佳/最高效的过滤方法是什么?

  • 针对不同情况分别选择语句
  • 使用合并

【问题讨论】:

标签: sql sql-server tsql


【解决方案1】:

使用这种方法可以避免使用多个 IF ELSE 条件和动态查询。

SELECT * FROM TBL
WHERE (@Name IS NULL OR Name = @Name) 
AND (@Age IS NULL OR Age = @Age)

【讨论】:

  • 你先生是个该死的天才。
  • 不要忘记括号,否则将不起作用。
  • 如果我尝试使用 LIKE 运算符而不是 equals 怎么办?会是 LIKE '%@Name%' 还是 %'@Name'% 或其他方式?
【解决方案2】:

你可以写你 WHERE 子句这样的东西.....

这是一个快速的解决方法,但一个糟糕的方法,,,,,

SELECT ......
FROM TABLE
WHERE 
     (@UserType IS NULL OR UserType = @UserType)
AND
    (@Customer IS NULL OR Customer = @Customer)
AND
    (@User IS NULL OR User = @User)
AND
    (<Similarly Other Conditions>)

编写这样的查询的正确方法应该是使用动态 SQL 和 sp_executesql

-- Optional Variables

Declare @UserType   VARCHAR(10) = NULL
    ,   @Customer   INT = 123
    ,   @User       INT = 123
    ,   @Sql        NVARCHAR(MAX);


-- Build SQL Dynamically 

 SET @Sql = N'  SELECT *
                FROM TABLE_Name
                WHERE 1 = 1 '
          + CASE WHEN @UserType IS NOT NULL THEN
            N' AND UserType = @UserType ' ELSE N' ' END
          +  CASE WHEN @Customer IS NOT NULL THEN
            N' AND Customer = @Customer ' ELSE N' ' END
          +  CASE WHEN @User IS NOT NULL THEN
            N' AND User = @User ' ELSE N' ' END

-- Finally Execute SQL 

 Exec sp_executesql @Sql
                , N'@UserType VARCHAR(10) , @Customer INT , @User INT'
                , @UserType
                , @Customer
                , @User;

【讨论】:

  • 为什么第二个更好?你能详细说明一下吗?泰。
  • 提供的第二种情况省略了任何未包含的参数。这样一来,SQL 就可以节省不完全检查它们的时间。
【解决方案3】:

您可以使用动态查询

SELECT @sql=
'SELECT DISTINCT [Test_Id], [Test].[Test_Name], [Test].[Test_Date]
    FROM [Test]
    WHERE (1 = 1)'

IF @start IS NOT NULL
    SELECT @sql = @sql + ' AND ([Test].[Test_Date] >= @start)'
IF @end IS NOT NULL
    SELECT @sql = @sql + ' AND ([Test].[Test_Date] <= @end)'

SELECT @paramlist = '@start datetime, 
    @end datetime'

EXEC sp_executesql @sql, @paramlist,
    @start, 
    @end

您也可以使用不同的查询,但是如果您有超过 2 个参数,那么代码会很烦人

IF(@start IS NULL)
    IF(@end IS NULL)
        SELECT ...
    ELSE
        SELECT ...
ELSE
    IF(@end IS NULL)
        SELECT ...
    ELSE
         SELECT ...

【讨论】:

  • 感谢您的提示建议。实际上,您的主要选择语句仅使用一个表,即“测试”,但在我的情况下,我必须使用连接等从 4-5 个不同的表中选择值。所以我认为动态sql可能有点乏味:)。无论如何我正在尝试它..谢谢
  • 为什么不能使用 JOIN 进行动态查询:FROM Test JOIN ...
  • 我知道这个问题是用 sql-server 标记的,但是 sp_executesql 在 mysql 中不起作用。
猜你喜欢
  • 2010-09-24
  • 2015-11-06
  • 1970-01-01
  • 2017-10-01
  • 2011-05-25
  • 2017-06-12
  • 2018-03-21
  • 1970-01-01
  • 2018-01-27
相关资源
最近更新 更多