这有点像Slow Exists Check的续集。亚历克斯的建议有效,并成功避免了代码重复,但我仍然得到了第二个问题。考虑下面的例子(来自AlexKuznetsov)。在其中,我有两个分支处理1个约束。如果我有2个可选约束,我最终会得到4个分支。基本上,分支数量随着约束的数量呈指数增长。
另一方面,如果我使用多语句表值函数或以其他方式使用临时表,SQL查询优化器无法帮助我,因此事情变得缓慢。我有点不信任动态SQL(我听说它也很慢)。
有人可以提供有关如何在不添加大量if语句的情况下添加更多约束的建议吗?
注意:我以前曾尝试将x is null or inpo = @inpo
链接在一起,但这很慢。请记住,虽然inpo = @inpo
测试可以通过某种索引黑魔法来处理,但无效测试最终会被评估为表中的每一行。
IF @inpo IS NULL BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
ORDER BY c;
END ELSE BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
WHERE inpo = @inpo
ORDER BY c;
END
变化二:2个约束:
IF @inpo IS NULL BEGIN
IF @inpo2 IS NULL BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
ORDER BY c;
END ELSE BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
WHERE inpo2 = @inpo2
ORDER BY c;
END
END ELSE BEGIN
IF @inpo2 IS NULL BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
WHERE inpo = @inpo
ORDER BY c;
END ELSE BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
WHERE inpo = @inpo AND
inpo2 = @inpo2
ORDER BY c;
END
END
答案 0 :(得分:5)
答案 1 :(得分:1)
在这种情况下,我使用了sp_executesql
,如Erland的文章所述:Using sp_executesql
每当使用动态SQL时,缺少权限可能是一个问题,所以我有一个真正的网络帐户进行单元测试,我将该帐户添加到实际角色,并且每当我测试动态SQL时,我都会冒充该真实帐户,如下所述: Database Unit Testing: Impersonation
答案 2 :(得分:0)
Select blah from foo
Where (@inpo1 is null or @inpo1 = inpo1)
and (@inpo2 is null or @inpo2 = inpo2)
显然这太慢了。有趣。
您是否考虑过代码生成?如果必须直接维护,那么冗长的查询只会出现重复问题。
答案 3 :(得分:0)
这是一个粗略的例子。修改WHERE子句中的LIKE语句,具体取决于您是否要在查询中使用“starts with”或“contains”或完全匹配。
CREATE PROCEDURE dbo.test
@name AS VARCHAR(50) = NULL,
@address1 AS VARCHAR(50) = NULL,
@address2 AS VARCHAR(50) = NULL,
@city AS VARCHAR(50) = NULL,
@state AS VARCHAR(50) = NULL,
@zip_code AS VARCHAR(50) = NULL
AS
BEGIN
SELECT [name],
address1,
address2,
city,
state,
zip_code
FROM my_table
WHERE ([name] LIKE @name + '%' OR @name IS NULL)
AND (address1 LIKE @address1 + '%' OR @address1 IS NULL)
AND (address2 LIKE @address2 + '%' OR @address2 IS NULL)
AND (city LIKE @city + '%' OR @city IS NULL)
AND (state LIKE @state + '%' OR @state IS NULL)
AND (zip_code LIKE @zip_code + '%' OR @zip_code IS NULL)
ORDER BY [name]
END
GO
答案 4 :(得分:0)
我意识到您的问题可能纯粹是学术问题,但如果您有真实世界的用例,您是否考虑过只针对最常见的情况提供优化查询?