Sql 表值参数上的条件Where语句?
我正在构建一个查询,它有一系列可选参数,其中一些是表值参数。我面临的问题是如何在这个查询中最有效地使用TVP 每个TVP都有以下类型:Sql 表值参数上的条件Where语句?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我正在构建一个查询,它有一系列可选参数,其中一些是表值参数。我面临的问题是如何在这个查询中最有效地使用TVP 每个TVP都有以下类型: TABLE( [variable] nvarchar(30)) INNER JOIN @TVP WHERE (SomeVar = @SameVar OR @SameVar IS NULL) OUTER APPLY (SELECT TOP(1) * from dbo.SomeTable tbl where tbl.SomeVar in (select *
TABLE( [variable] nvarchar(30))
INNER JOIN @TVP
WHERE (SomeVar = @SameVar OR @SameVar IS NULL)
OUTER APPLY
(SELECT TOP(1) * from dbo.SomeTable tbl where tbl.SomeVar in
(select * from @TVP) or not exists (select * from @TVP)
AND tbl.SomeVar = SomeVar)
WHERE (tbl.SomeVar in (SELECT * FROM @TVP) or not exists (SELECT * from @TVP))
我知道我通常可以:
TABLE( [variable] nvarchar(30))
INNER JOIN @TVP
WHERE (SomeVar = @SameVar OR @SameVar IS NULL)
OUTER APPLY
(SELECT TOP(1) * from dbo.SomeTable tbl where tbl.SomeVar in
(select * from @TVP) or not exists (select * from @TVP)
AND tbl.SomeVar = SomeVar)
WHERE (tbl.SomeVar in (SELECT * FROM @TVP) or not exists (SELECT * from @TVP))
要过滤掉不在TVP列表中的任何内容,但如果我决定在查询中不向TVP传递任何值,该怎么办?然后将不返回任何内容(因为内部联接)
这通常通过条件where语句完成:
TABLE( [variable] nvarchar(30))
INNER JOIN @TVP
WHERE (SomeVar = @SameVar OR @SameVar IS NULL)
OUTER APPLY
(SELECT TOP(1) * from dbo.SomeTable tbl where tbl.SomeVar in
(select * from @TVP) or not exists (select * from @TVP)
AND tbl.SomeVar = SomeVar)
WHERE (tbl.SomeVar in (SELECT * FROM @TVP) or not exists (SELECT * from @TVP))
但是,对于TVP,它不能为null(至少我没有发现)
我发现实现这一目标的一种方法是:
TABLE( [variable] nvarchar(30))
INNER JOIN @TVP
WHERE (SomeVar = @SameVar OR @SameVar IS NULL)
OUTER APPLY
(SELECT TOP(1) * from dbo.SomeTable tbl where tbl.SomeVar in
(select * from @TVP) or not exists (select * from @TVP)
AND tbl.SomeVar = SomeVar)
WHERE (tbl.SomeVar in (SELECT * FROM @TVP) or not exists (SELECT * from @TVP))
不幸的是,这种方法非常慢
或者,我尝试过:
TABLE( [variable] nvarchar(30))
INNER JOIN @TVP
WHERE (SomeVar = @SameVar OR @SameVar IS NULL)
OUTER APPLY
(SELECT TOP(1) * from dbo.SomeTable tbl where tbl.SomeVar in
(select * from @TVP) or not exists (select * from @TVP)
AND tbl.SomeVar = SomeVar)
WHERE (tbl.SomeVar in (SELECT * FROM @TVP) or not exists (SELECT * from @TVP))
这要快得多,但我还是觉得可能不太理想
任何帮助或想法都将不胜感激!如果我能澄清任何事情,请告诉我……提前谢谢
编辑:
TABLE( [variable] nvarchar(30))
INNER JOIN @TVP
WHERE (SomeVar = @SameVar OR @SameVar IS NULL)
OUTER APPLY
(SELECT TOP(1) * from dbo.SomeTable tbl where tbl.SomeVar in
(select * from @TVP) or not exists (select * from @TVP)
AND tbl.SomeVar = SomeVar)
WHERE (tbl.SomeVar in (SELECT * FROM @TVP) or not exists (SELECT * from @TVP))
所以,我想到了这个,除非有人有更好的解决方案,否则我可能会使用它:
INNER JOIN @TVP tvp
ON (tvp.SomeVar = tbl.SomeVar or tvp.SomeVar is null)
您是否尝试过:
DECLARE @UseTVP int
SET @UseTVP = (SELECT COUNT(*) FROM @TVP)
SELECT TOP 1 *
FROM dbo.SomeTable tbl
LEFT JOIN @TVP tvp
ON tbl.SomeVar = tvp.SomeVar
WHERE (tvp.SomeVar IS NOT NULL
OR @UseTVP = 0)
那么,如果我在查询过程中没有使用TVP呢?然后它总是空的,我不会得到结果,对吗?我该如何选择使用TVP?@Brett:我已经编辑了我的答案。我不确定这是否比你已经尝试过的更好。这看起来相当不错,我想我将介绍我现在掌握的两种方法,并从那里开始。。。。谢谢你的帮助!这个小金块太棒了!我们仅限于sql2005,因此没有TVP,但无论如何,这种方法基本上允许您对传入参数的“列表”(基本上是一个分隔字符串,然后解析为#temp table)进行条件联接,并允许列表可能为空(即未传递)且不对该参数进行过滤,基本上返回“all”。您可以在新的“tvp”上执行左连接,并添加另一个“和[list parameter]。SomeVar不为NULL或@Use[list for the parameter]=0”。我花了一段时间才找到答案,但这个答案,嗯,就是答案……你当然可以使用参数列表,即“或[list parameter]。SomeVar不为NULL或@Use[list for the parameter]=0”或你查询时需要的任何东西:-)