2013-05-12 76 views
0

直接在“into @gutsTVP”之后的左paren将其分解。
该错误是在第12行
右括号。如果删除第一套围绕它运行的第一个工会括号,但它返回错误的答案,然后第一个工会使用带插入的前导圆括号的语法错误

DECLARE @gutsTVP AS TABLE (sID INT PRIMARY KEY); 
insert into @gutsTVP 
(
     select distinct [ftsIndexWordOnce].[sID] 
     from [ftsIndexWordOnce] with (nolock) 
     where [ftsIndexWordOnce].[wordID] in (1,2) 
    union 
     select distinct [ftsIndexWordOnceB].[sID] 
     from [ftsIndexWordOnceB] with (nolock) 
     where [ftsIndexWordOnceB].[wordID] in (5,6) 
) 
intersect 
(
     select distinct [ftsIndexWordOnce].[sID] 
     from [ftsIndexWordOnce] with (nolock) 
     where [ftsIndexWordOnce].[wordID] in (9,10,11,12) 
    union 
     select distinct [ftsIndexWordOnceB].[sID] 
     from [ftsIndexWordOnceB] with (nolock) 
     where [ftsIndexWordOnceB].[wordID] in (13,14,15,16) 
) 
select [guts].[sID] from @gutsTVP as [guts] 
join [docSVsys] with (nolock) 
    on [docSVsys].[sID] = [guts].[sID] 
order by [docSVsys].[sParID], [docSVsys].[sID] 
前应用交叉

包含最终连接,因为这是TABLE的用途。
如果我加入派生表,它不知道PK并且慢得多。

是的,我知道可以重新考虑这一点,不要有一个领先的左派paren。
这是一个简化的查询。
需要能够处理领先的左派paren。

下面的技巧将语法转化为工作。
但现在连接速度较慢,因为它不知道PK。
不能有SID为PK和接受空

DECLARE @gutsTVP AS TABLE (sID INT PRIMARY KEY); 
insert into @gutsTVP 
select 0 -- real PK starts at 1 
union 
(  
     select distinct [ftsIndexWordOnce].[sID] 
     from [ftsIndexWordOnce] with (nolock) 
     where [ftsIndexWordOnce].[wordID] in (1,2) 
    union 
     select distinct [ftsIndexWordOnceB].[sID] 
     from [ftsIndexWordOnceB] with (nolock) 
     where [ftsIndexWordOnceB].[wordID] in (5,6) 
) 
intersect 
(
     select distinct [ftsIndexWordOnce].[sID] 
     from [ftsIndexWordOnce] with (nolock) 
     where [ftsIndexWordOnce].[wordID] in (9,10,11,12) 
    union 
     select distinct [ftsIndexWordOnceB].[sID] 
     from [ftsIndexWordOnceB] with (nolock) 
     where [ftsIndexWordOnceB].[wordID] in (13,14,15,16) 
) 
select [guts].[sID] from @gutsTVP as [guts] 
join [docSVsys] with (nolock) 
    on [docSVsys].[sID] = [guts].[sID] 
where [guts].[sID] > 0 
order by [docSVsys].[sParID], [docSVsys].[sID] 

回答

2

尝试的CTE来代替:

DECLARE @gutsTVP AS TABLE (sID INT PRIMARY KEY); 
; WITH a AS (
     select [ftsIndexWordOnce].[sID] 
     from [ftsIndexWordOnce] with (nolock) 
     where [ftsIndexWordOnce].[wordID] in (1,2) 
    union 
     select [ftsIndexWordOnceB].[sID] 
     from [ftsIndexWordOnceB] with (nolock) 
     where [ftsIndexWordOnceB].[wordID] in (5,6) 
) 
, b AS (
     select [ftsIndexWordOnce].[sID] 
     from [ftsIndexWordOnce] with (nolock) 
     where [ftsIndexWordOnce].[wordID] in (9,10,11,12) 
    union 
     select [ftsIndexWordOnceB].[sID] 
     from [ftsIndexWordOnceB] with (nolock) 
     where [ftsIndexWordOnceB].[wordID] in (13,14,15,16) 
) 
insert into @gutsTVP 
SELECT * FROM a 
    intersect 
SELECT * FROM b; 

select [guts].[sID] from @gutsTVP as [guts] 
join [docSVsys] with (nolock) 
    on [docSVsys].[sID] = [guts].[sID] 
order by [docSVsys].[sParID], [docSVsys].[sID] 

还要注意的是,你可以放弃distinct小号,因为他们已被union所默许的。

+0

我可以删除独特但它运行速度明显慢 - 真的。这工作+1,但我想以线性方式建立该语法。我更新了我的工作。 – Paparazzi 2013-05-12 20:06:39

+0

看起来不错。 parens有点棘手 - 如果没有INSERT,原来的查询就会变得语法正确。但是当一个开放paren紧跟在一个INSERT之后时,SQL Server需要一个列列表而不是一组值。 – 2013-05-12 20:17:21

+0

在进一步的测试中,这比我的黑客执行得更好 – Paparazzi 2013-05-12 21:01:10