为搜索创建动态SQL查询
我需要创建一个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]
中使用条件,其中没有固定条件,条件可能有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谢谢你提供了那篇文章的链接,我以前没有看到过任何关于这种优化形式的讨论。似乎对每个参数组合进行不同的查询可能是一种方法,但我猜它可能需要几乎逐个系统地进行测试……正确。可能是这样永远不要遭受参数嗅探的痛苦。只是要意识到这一点,以防万一。