简体   繁体   中英

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:

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."

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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