简体   繁体   English

在动态查询中使用“ IN”运算符

[英]Using “IN” operator in a dynamic query

i've been searching SO for a while and found nothing related to this. 我已经搜索了一段时间,没有发现与此相关的任何信息。

We use heavily the dynamic approach for most of our queries like this: 我们在大多数查询中都使用动态方法,如下所示:

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

This way the query gets filtered dynamically if there's a value on the parameter 这样,如果参数上有值,查询将被动态过滤

But the problem comes when trying the same stuff with several IDs like so: 但是当尝试使用多个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 throws an error "Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression." Sql引发错误“子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。”

that's totally normal and expected, my question is: 这是完全正常的预期,我的问题是:

Is there a way to dynamically do this kind of filtering ? 有没有办法动态地进行这种过滤?

The solution we use is this: 我们使用的解决方案是这样的:

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

But it's not an option when the query is massive and feeding a table variable is overkill for this. 但是,如果查询量很大,并且提供表变量对此是过大的,则不是一种选择。 Hope i made my point and someone is kind enough to help me find a solution to this. 希望我能指出我的观点,并且有人愿意帮助我找到解决方案。

PS: Using sp_ExecuteSql is not an option in this scenario either, sorry. PS:在这种情况下,也不选择使用sp_ExecuteSql ,抱歉。

How you should do this is with a table parameter. 应该使用表参数执行此操作。

But if you want to persist in this approach. 但是如果您要坚持这种方法。

Declare @ContactId VarChar(8000) 

Select @ContactId = '1,2,3'
Select *  
From Person.Contact 
where ',' + @contactID + ',' like '%,'+convert(varchar(50),contactid)+',%'

Try this 尝试这个

Select * 
From Person.Contact
Where (
           len(@contactid) > 0 AND 
           ContactID IN (Select id From dbo.SplitString(@ContactId,','))) 
or 1 = 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM