为搜索创建动态SQL查询

为搜索创建动态SQL查询,sql,sql-server,Sql,Sql Server,我需要创建一个SQL查询来从表返回数据,并在中使用条件,其中没有固定条件,条件可能有2个或3个参数,我希望避免使用IF@PARAMETER>0。我想用一种更好更干净的方法来解决这个问题 这是我的疑问: CREATE PROCEDURE GetAllUsers(@p1 , @p2 , @p3 , @p4) AS BEGIN SELECT firstName, lastName, email FROM [USERS]

我需要创建一个SQL查询来从表返回数据,并在
中使用条件,其中
没有固定条件,条件可能有2个或3个参数,我希望避免使用
IF@PARAMETER>0
。我想用一种更好更干净的方法来解决这个问题

这是我的疑问:

CREATE PROCEDURE GetAllUsers(@p1 , @p2 , @p3 , @p4)
AS
BEGIN
    SELECT
        firstName,
        lastName,
        email
    FROM 
        [USERS]
    WHERE 
        id = @p4 AND firstName = @p2
END

如何解决此问题?

您可以将
NULL
传递给不需要的参数,并编写如下查询

SELECT firstName, lastName, email
FROM [USERS]
WHERE (
        @p4 IS NULL
        OR id = @p4
        )
    AND (
        @p2 IS NULL
        OR firstName = @p2
        )
类似地,您可以通过添加其他参数来构建查询

注意:您的
创建过程的语法不正确,您需要提及参数的数据类型

您还可以使用默认值设置参数。您的最终SP应该如下所示

CREATE PROCEDURE GetAllUsers (
     @p1 INT = NULL
    ,@p2 VARCHAR(100) = NULL
    ,@p3 VARCHAR(100) = NULL
    ,@p4 VARCHAR(100) = NULL
    )
AS
BEGIN
    SELECT firstName
          ,lastName
          ,email
    FROM [USERS]
    WHERE (
            @p4 IS NULL
            OR id = @p4
            )
        AND (
            @p2 IS NULL
            OR firstName = @p2
            )
    --Add remaining conditions
END

您可以使用
COALESCE
使参数等于当参数值为
NULL
时要与之进行比较的列,这样,如果通过参数值的
NULL
,则测试通过。例如:

SELECT
    firstName,
    lastName,
    email
FROM [USERS]
WHERE id=COALESCE(@p4,id) AND firstName=COALESCE(@p2,firstName)
因此,当调用您的过程并希望获取所有
John
而不考虑
id
时,您将使用

GetAllUsers('somevalue' , 'John' , 'someothervalue' , NULL)

我有疑问地说,我不喜欢用if和相同的方式。有人告诉我使用json,但我不知道如何使用这种方式。我唯一能想到的另一种方法是创建动态查询,这也需要if条件来构建查询。我不建议在这种情况下使用动态查询。在非常大的表上构建动态查询(省略对
NULL
参数的测试)可能会更快,但这应该取决于查询优化程序的工作情况(因为它应该能够看到
@p*
是常量,并将
合并
s减少为单个值)。这类查询(通常称为“厨房水槽”查询)可能会受到参数嗅探的影响。@Nick.McDermaid谢谢你提供了那篇文章的链接,我以前没有看到过任何关于这种优化形式的讨论。似乎对每个参数组合进行不同的查询可能是一种方法,但我猜它可能需要几乎逐个系统地进行测试……正确。可能是这样永远不要遭受参数嗅探的痛苦。只是要意识到这一点,以防万一。