【发布时间】:2012-10-17 21:36:03
【问题描述】:
我已经搜索了一段时间,没有找到与此相关的内容。
对于大多数查询,我们大量使用动态方法,如下所示:
Declare @ContactId VarChar(8000)
Select @ContactId = '1'
Select *
From Person.Contact
Where 1 = 1 And
Case When Len(Ltrim(Rtrim(@ContactId))) = 0 Then 1 Else ContactID End =
Case When Len(Ltrim(Rtrim(@ContactId))) = 0 Then 1 Else @ContactId End
这样,如果参数上有值,查询就会被动态过滤
但是当使用多个 ID 尝试相同的东西时,问题就来了:
Declare @ContactId VarChar(8000)
Select @ContactId = '1,2,3'
Select *
From Person.Contact
Where 1 = 1 And
Case When Len(Ltrim(Rtrim(@ContactId))) = 0 Then 1 Else ContactID End In (
Select Case When Len(Ltrim(Rtrim(@ContactId))) = 0 Then 1 Else ( Select id From dbo.SplitString(@ContactId,',') ) End )
Sql 抛出错误“子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。”
这是完全正常和预期的,我的问题是:
有没有办法动态地进行这种过滤?
我们使用的解决方案是这样的:
Declare @Table Table(
Col1 Int,
Col2 Int,
Col3 Int
)
Insert @Table
Select Col1, Col2, Col3
From Person.Contact
Where [many filters except the in clause filters]
If Len(Ltrim(RTrim(@ContactId))) > 0
Select *
From @Table
Where ContactId In ( Select Id From dbo.SplitString(@ContactId, ',') )
Else
Select *
From @Table
但是,当查询量很大并且为此提供表变量过大时,这不是一个选择。希望我表达了我的观点,并且有人能帮助我找到解决方案。
PS:在这种情况下也不能使用sp_ExecuteSql,抱歉。
【问题讨论】:
-
如果你排除了你做某事的两种方式,那么是的,你会很难过。
标签: sql sql-server tsql dynamic-sql in-operator