【问题标题】:Using "IN" operator in a dynamic query在动态查询中使用“IN”运算符
【发布时间】: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


【解决方案1】:

您应该如何使用表格参数来做到这一点。

但如果你想坚持这种方法。

Declare @ContactId VarChar(8000) 

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

【讨论】:

  • 这种方法很有趣,但可悲的是,如果参数为空,它不会选择任何东西:(
  • @SamCcp 添加or len(@contactID)=0
  • 好的,现在我们到了某个地方,通过添加该条件,即使参数为空,它也会带来所需的数据,但我不能玩很多这样的条件,对吧?我的意思是我怎么能搜索另一个条件说... @EmailPromotion = '1,2'
  • @SamCcp 当然可以。坚持(围绕喜欢/或)并添加任意数量的其他过滤器。例如:and (','+@emailpromotion+',' like '%,' + emailpromotion + ',%')
  • 是的,我刚刚想通了,谢谢,我会运行一些查询并测试性能,与此同时,您先生赢得了一个粉丝。谢谢。
【解决方案2】:

试试这个

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

【讨论】:

  • 与上一个答案相同,如果参数为空,则不显示任何内容,并且必须省略 OR 部分,因为它会将所有行都放在表中。
猜你喜欢
  • 2016-04-09
  • 2020-01-02
  • 2015-01-30
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多