求教一条SQL,,,当条件为空时舍弃,,,不为空时则用AND连接起来

时间:2021-08-27 04:22:46
declare @paraState char(100) 
SELECT sum(v.contract_amount) as ContractAmount, v.CustomerType
FROM V_ContractProjectInvoice v 
WHERE 
(v.business_category in (@paraBusinessCategory)) 

and v.project_deptid in (@paraBusinessCenter) 

and v.carry_deptmentid in (@paraDepartment) 
v.sign_date>'1900-01-01' and v.sign_date<'2900-01-01'
GROUP BY v.CustomerType



例如,,,当(@paraBusinessCenter)有值时,,就在SQL语句中用and 连接起来,,and v.project_deptid in (@paraBusinessCenter) 

当没有值时,,,,直接让"and v.project_deptid in (@paraBusinessCenter) "在SQL语句的条件中失效....当不存在一样,,,,

只能用一条SQL语句,,不能在程序代码中实现........

跪求各位啦

12 个解决方案

#1


把判断语句放到存储过程中去做.

只用语句不好实现.

#2


把判断语句,执行语言等放到存储过程中去做.
通过传进去的参数来判断是否什么样条件来查询. 

只用语句不好实现.

#3


如今都流行用一句sql实现问题?

有时候我喜欢拆分sql语句

#4


用过程吧
好写,好测试

#5


要让某条件失效:
比如,以@fieldx,@fieldY 变量分别来过滤 fieldX,fieldY 列.
 当任一参数为null时,过滤失效
select * from tb where 1=1 and fieldX = isnull(@fieldX,fieldX) and fieldY=isnull(@fieldY,fieldY)



而你的问题,也可以这么来处理. 遗憾的是,你本身的写法就有问题:

(v.business_category in (@paraBusinessCategory)) 
in (....) 这里应该是一个集合.
而你的 @paraBusinessCategory 只是一个普通变量,很可能是'aa,bb,cc' 或'1,2,3' 这样的字串变量,这当然行不通的.

你的语句应该改用charindex或 like

charindex(',' + rtrim(v.business_category) + ','   ,    ',' + @paraBusinessCategory + ',') > 0 --like的写法不写了.一新的,注意加前后辍','就可以了.


如果应用到 @paraBussnessCategory 为 null 时此条件失效,那么跟我写的例子一样的处理方式:

charindex(',' + rtrim(v.business_category) + ','   ,    ',' + isnull(@paraBusinessCategory,rtrim(v.business_category)) + ',') > 0 


其它几个条件,同样的处理方式.


随手敲的,可能手误.

#6


倒,,,早知道早点上来看帖子了,,,

我已经写成一个存储过程了,,问题又来了....

因为我是在reporting service里面使用的,所以我调用这个存储过程的时候这样写
exec currentCompareLastYearCustomerSource 
@paraBusinessCategory,
@paraBusinessCenter,
@paraDepartment,
@paraSignDateStart,
@paraSignDateEnd

但如果@paraBusinessCategory有多个值,就像'1,2,3'这样,,就会被认为是多个参数,,结果报告了参数过多的错误.


唉.......头痛死了

#7


引用 5 楼 fcuandy 的回复:
要让某条件失效: 
比如,以@fieldx,@fieldY 变量分别来过滤 fieldX,fieldY 列. 
 当任一参数为null时,过滤失效 

SQL codeselect * from tb where 1=1 and fieldX = isnull(@fieldX,fieldX) and fieldY=isnull(@fieldY,fieldY)




而你的问题,也可以这么来处理. 遗憾的是,你本身的写法就有问题: 

(v.business_category in (@paraBusinessCategory))  
in (....) 这里应该是一个集合. 
而你的 @paraBusinessCategor…



  @fieldX=''的时候,,,满不满足isnull的条件???

#8


@fieldX='' 那么就不是NULL.
那么要多处理一步,用NULLIF看看它是不是为'',如果是的话,处理成NULL,然后用ISNULL处理就行了
当然,你也可以用case when


select * from tb where 1=1 and fieldX = isnull(NULLIF(@fieldX,''),fieldX) and fieldY=isnull(NULLIF(@fieldY,''),fieldY)

#9


declare @paraState char(100)  
SELECT sum(v.contract_amount) as ContractAmount, v.CustomerType 
FROM V_ContractProjectInvoice v  
WHERE  
(v.business_category in (@paraBusinessCategory)) 
 

--and v.project_deptid in (@paraBusinessCenter)  
--换成
and (isnull(@paradepartment,'')='' or v.project_deptid in (@paraBusinessCenter))


and v.carry_deptmentid in (@paraDepartment)  
v.sign_date> '1900-01-01' and v.sign_date <'2900-01-01' 
GROUP BY v.CustomerType 

另,你的v.project_deptid 应该是INT类型吧,如果是INT类型就不要理会5L下面的建议:
----------------------------------------
而你的问题,也可以这么来处理. 遗憾的是,你本身的写法就有问题: 

(v.business_category in (@paraBusinessCategory))  
in (....) 这里应该是一个集合. 
而你的 @paraBusinessCategory 只是一个普通变量,很可能是'aa,bb,cc' 或'1,2,3' 这样的字串变量,这当然行不通的. 

你的语句应该改用charindex或 like 


SQL codecharindex(',' + rtrim(v.business_category) + ','   ,    ',' + @paraBusinessCategory + ',') > 0 --like的写法不写了.一新的,注意加前后辍','就可以了. 

-----------------------------------------

#10


引用 6 楼 fb777 的回复:
倒,,,早知道早点上来看帖子了,,, 

我已经写成一个存储过程了,,问题又来了.... 

因为我是在reporting service里面使用的,所以我调用这个存储过程的时候这样写 
exec currentCompareLastYearCustomerSource  
@paraBusinessCategory, 
@paraBusinessCenter, 
@paraDepartment, 
@paraSignDateStart, 
@paraSignDateEnd 

但如果@paraBusinessCategory有多个值,就像'1,2,3'这样,,就会被认为是多个参数,,结果报告了参数…

如果你的v.business_category 是数值型的不是字符串型的
     @paraBusinessCategory='1,2,3' 是可以的,下面的建议也是对的。
     在存储过程中拼动态SQL时应该加引号:
     (v.business_category in (@paraBusinessCategory))  
     这句这样写是不行的:
      set @sqlstr = @sqlstr +'(v.business_category in ('+@paraBusinessCategory+'))'
     应该这样写:
    set @sqlstr = @sqlstr +'(v.business_category in ('''+@paraBusinessCategory+'''))'
但如果你的v.business_category 是字符串型的
     @paraBusinessCategory='1,2,3' 是不准确的参数,为了便于动态语句拼接,应该处理参数:
     @paraBusinessCategory=''''''+replace(@paraBusinessCategory,',',''''',''''')+''''''
     然后再按照上面的进行处理



#11


呵呵,楼主没用动态语句, 你用的动态语句,当然不必理会那个建议了.

#12


引用 10 楼 JiangHongTao 的回复:
引用 6 楼 fb777 的回复:
倒,,,早知道早点上来看帖子了,,,  

我已经写成一个存储过程了,,问题又来了....  

因为我是在reporting service里面使用的,所以我调用这个存储过程的时候这样写  
exec currentCompareLastYearCustomerSource   
@paraBusinessCategory,  
@paraBusinessCenter,  
@paraDepartment,  
@paraSignDateStart,  
@paraSignDateEnd  

但如果@paraBusinessCategory有多个值,就像'1,2,3'这样,,就…


唉,,我晕了,,,传进来的参数是'1','2','3'

所以本来是exec currentCompareLastYearCustomerSource   
@paraBusinessCategory,  
@paraBusinessCenter,  
@paraDepartment,  
@paraSignDateStart,  
@paraSignDateEnd 

5个参数的,,一替换参数就变成了...

exec currentCompareLastYearCustomerSource   
'1','2','3', 
@paraBusinessCenter,  
@paraDepartment,  
@paraSignDateStart,  
@paraSignDateEnd 

变成了7个参数,,所以抛出了参数个数过多的错误...

#1


把判断语句放到存储过程中去做.

只用语句不好实现.

#2


把判断语句,执行语言等放到存储过程中去做.
通过传进去的参数来判断是否什么样条件来查询. 

只用语句不好实现.

#3


如今都流行用一句sql实现问题?

有时候我喜欢拆分sql语句

#4


用过程吧
好写,好测试

#5


要让某条件失效:
比如,以@fieldx,@fieldY 变量分别来过滤 fieldX,fieldY 列.
 当任一参数为null时,过滤失效
select * from tb where 1=1 and fieldX = isnull(@fieldX,fieldX) and fieldY=isnull(@fieldY,fieldY)



而你的问题,也可以这么来处理. 遗憾的是,你本身的写法就有问题:

(v.business_category in (@paraBusinessCategory)) 
in (....) 这里应该是一个集合.
而你的 @paraBusinessCategory 只是一个普通变量,很可能是'aa,bb,cc' 或'1,2,3' 这样的字串变量,这当然行不通的.

你的语句应该改用charindex或 like

charindex(',' + rtrim(v.business_category) + ','   ,    ',' + @paraBusinessCategory + ',') > 0 --like的写法不写了.一新的,注意加前后辍','就可以了.


如果应用到 @paraBussnessCategory 为 null 时此条件失效,那么跟我写的例子一样的处理方式:

charindex(',' + rtrim(v.business_category) + ','   ,    ',' + isnull(@paraBusinessCategory,rtrim(v.business_category)) + ',') > 0 


其它几个条件,同样的处理方式.


随手敲的,可能手误.

#6


倒,,,早知道早点上来看帖子了,,,

我已经写成一个存储过程了,,问题又来了....

因为我是在reporting service里面使用的,所以我调用这个存储过程的时候这样写
exec currentCompareLastYearCustomerSource 
@paraBusinessCategory,
@paraBusinessCenter,
@paraDepartment,
@paraSignDateStart,
@paraSignDateEnd

但如果@paraBusinessCategory有多个值,就像'1,2,3'这样,,就会被认为是多个参数,,结果报告了参数过多的错误.


唉.......头痛死了

#7


引用 5 楼 fcuandy 的回复:
要让某条件失效: 
比如,以@fieldx,@fieldY 变量分别来过滤 fieldX,fieldY 列. 
 当任一参数为null时,过滤失效 

SQL codeselect * from tb where 1=1 and fieldX = isnull(@fieldX,fieldX) and fieldY=isnull(@fieldY,fieldY)




而你的问题,也可以这么来处理. 遗憾的是,你本身的写法就有问题: 

(v.business_category in (@paraBusinessCategory))  
in (....) 这里应该是一个集合. 
而你的 @paraBusinessCategor…



  @fieldX=''的时候,,,满不满足isnull的条件???

#8


@fieldX='' 那么就不是NULL.
那么要多处理一步,用NULLIF看看它是不是为'',如果是的话,处理成NULL,然后用ISNULL处理就行了
当然,你也可以用case when


select * from tb where 1=1 and fieldX = isnull(NULLIF(@fieldX,''),fieldX) and fieldY=isnull(NULLIF(@fieldY,''),fieldY)

#9


declare @paraState char(100)  
SELECT sum(v.contract_amount) as ContractAmount, v.CustomerType 
FROM V_ContractProjectInvoice v  
WHERE  
(v.business_category in (@paraBusinessCategory)) 
 

--and v.project_deptid in (@paraBusinessCenter)  
--换成
and (isnull(@paradepartment,'')='' or v.project_deptid in (@paraBusinessCenter))


and v.carry_deptmentid in (@paraDepartment)  
v.sign_date> '1900-01-01' and v.sign_date <'2900-01-01' 
GROUP BY v.CustomerType 

另,你的v.project_deptid 应该是INT类型吧,如果是INT类型就不要理会5L下面的建议:
----------------------------------------
而你的问题,也可以这么来处理. 遗憾的是,你本身的写法就有问题: 

(v.business_category in (@paraBusinessCategory))  
in (....) 这里应该是一个集合. 
而你的 @paraBusinessCategory 只是一个普通变量,很可能是'aa,bb,cc' 或'1,2,3' 这样的字串变量,这当然行不通的. 

你的语句应该改用charindex或 like 


SQL codecharindex(',' + rtrim(v.business_category) + ','   ,    ',' + @paraBusinessCategory + ',') > 0 --like的写法不写了.一新的,注意加前后辍','就可以了. 

-----------------------------------------

#10


引用 6 楼 fb777 的回复:
倒,,,早知道早点上来看帖子了,,, 

我已经写成一个存储过程了,,问题又来了.... 

因为我是在reporting service里面使用的,所以我调用这个存储过程的时候这样写 
exec currentCompareLastYearCustomerSource  
@paraBusinessCategory, 
@paraBusinessCenter, 
@paraDepartment, 
@paraSignDateStart, 
@paraSignDateEnd 

但如果@paraBusinessCategory有多个值,就像'1,2,3'这样,,就会被认为是多个参数,,结果报告了参数…

如果你的v.business_category 是数值型的不是字符串型的
     @paraBusinessCategory='1,2,3' 是可以的,下面的建议也是对的。
     在存储过程中拼动态SQL时应该加引号:
     (v.business_category in (@paraBusinessCategory))  
     这句这样写是不行的:
      set @sqlstr = @sqlstr +'(v.business_category in ('+@paraBusinessCategory+'))'
     应该这样写:
    set @sqlstr = @sqlstr +'(v.business_category in ('''+@paraBusinessCategory+'''))'
但如果你的v.business_category 是字符串型的
     @paraBusinessCategory='1,2,3' 是不准确的参数,为了便于动态语句拼接,应该处理参数:
     @paraBusinessCategory=''''''+replace(@paraBusinessCategory,',',''''',''''')+''''''
     然后再按照上面的进行处理



#11


呵呵,楼主没用动态语句, 你用的动态语句,当然不必理会那个建议了.

#12


引用 10 楼 JiangHongTao 的回复:
引用 6 楼 fb777 的回复:
倒,,,早知道早点上来看帖子了,,,  

我已经写成一个存储过程了,,问题又来了....  

因为我是在reporting service里面使用的,所以我调用这个存储过程的时候这样写  
exec currentCompareLastYearCustomerSource   
@paraBusinessCategory,  
@paraBusinessCenter,  
@paraDepartment,  
@paraSignDateStart,  
@paraSignDateEnd  

但如果@paraBusinessCategory有多个值,就像'1,2,3'这样,,就…


唉,,我晕了,,,传进来的参数是'1','2','3'

所以本来是exec currentCompareLastYearCustomerSource   
@paraBusinessCategory,  
@paraBusinessCenter,  
@paraDepartment,  
@paraSignDateStart,  
@paraSignDateEnd 

5个参数的,,一替换参数就变成了...

exec currentCompareLastYearCustomerSource   
'1','2','3', 
@paraBusinessCenter,  
@paraDepartment,  
@paraSignDateStart,  
@paraSignDateEnd 

变成了7个参数,,所以抛出了参数个数过多的错误...