SQL 数据库中的存储过程的参数问题(case when)

1、SQL 数据库中的存储过程的参数问题

http://bbs.csdn.net/topics/390640511?page=1#post-396062228

怎么将SQL数据库中的存储过程中的参数既作为输出变量又作为输出变量?

[sql]  view plain copy
  1. --drop proc proc_test  
  2. --go  
  3.   
  4.   
  5. create proc dbo.proc_test  
  6. @in int,  
  7. @out int out,  
  8. @in_out int output  
  9. as  
  10.   
  11. select @out = @in + @in_out,  --1 + 2 = 3  
  12.        @in_out = @out + 1     --3 + 1 = 4  
  13. go  
  14.   
  15.   
  16. declare @in_p int  
  17. declare @out_p int  
  18. declare @in_out_p int  
  19.   
  20. set @in_p = 1;  
  21. set @in_out_p = 2  
  22.   
  23. exec dbo.proc_test @in_p,  
  24.                    @out_p out,  
  25.                    @in_out_p output  
  26.                      
  27.   
  28. select @in_p,    --输入参数  
  29.        @out_p,   --输出参数  
  30.        @in_out_p --输入,输出参数  
  31. /*  
  32. (无列名)   (无列名)   (无列名)  
  33. 1   3   4  
  34. */         
  35.          

2、在存储过程中的参数问题。

下面是问题:
[sql]  view plain copy
  1. create table #tableTest(id int identity , name varchar(20),age int,)  
  2. go  
  3. insert into #tableTest  
  4. select '小明',23 union all  
  5. select '小红',28 union all  
  6. select '小军',27  
  7. go  
  8. select *from #tableTest  
  9. go  
  10.   
  11.   
  12. create proc procTest  
  13. @name varchar(20),  
  14. @age int,  
  15. @IDs varchar(30)  
  16. as  
  17. begin  
  18. select *from #tableTest where 1=1  
  19. end  
  20.   
  21. --当我传入@name参数等于 小明,23岁,还有ID在(1,3)的时候  
  22. --我怎么可以弄成可选的参数  
  23. --比如,name不为空时候  
  24. select *from #tableTest where 1=1 and name like '小明'  
  25. --如果name参数为空的时候,IDs参数不为空的时候  
  26. select *from #tableTest where 1=1 and id in(1,3)  
  27. --请问一下,就有参数不为空的时候存储过程中的SQL追加条件,为空的时候就不追加,这样带可选参数的存储过程怎么写,以及怎么调用,请帮小弟写一个实例  
这种问题,本质上就是根据传入的参数不同,进行不同的查询,也就是where 后面的查询条件是动态的。
一般有2中处理方式,一种就是写动态语句,但动态语句由于是动态拼接字符串,所以比较难维护,而且如果存储过程需要执行多次,那么每次都需要重新编译,但每次生成的执行计划,应该是比较优化的。但如果拼接字符串部分,只是少量的话,还是可以用动态语句的,下面我的解法就是用动态语句来实现的,结构清晰,易于维护。
另一种,就是通过在where语句后面写case when来进行判断,这种方法的好处是不用动态拼接语句,但不易于理解,也不易于修改,因为别人不一定能理解你这么写的意思。另一个问题就是性能的问题,因为在原来的公司就用过这种方法,一段时间后,查询非常慢,本来几秒就能出结果,后来几分钟都出不了结果。说实在的,这种方法要求较高的技巧性,也容易出错,不建议使用。
下面是我的解法,用了动态语句来实现,但考虑了维护、测试方面的要求:
[sql]  view plain copy
  1. --drop table #tableTest  
  2.   
  3. create table #tableTest(id int identity , name varchar(20),age int,)  
  4. go  
  5. insert into #tableTest  
  6. select '小明',23 union all  
  7. select '小红',28 union all  
  8. select '小军',27  
  9. go  
  10. select *from #tableTest  
  11. go  
  12.   
  13. create proc procTest  
  14. @name varchar(20)=null,@age int = null,@IDs varchar(30) = null  
  15. as  
  16.   
  17. declare @sql nvarchar(max);  
  18. set @sql = '';  
  19.   
  20. set @sql = 'select * from #tableTest where 1 = 1';  
  21.   
  22. set @sql = @sql +   
  23.            case when @name is not null  
  24.                      then ' and name like ' + QUOTENAME(@name +'%','''')  
  25.                 when @age is not null  
  26.                      then ' and age = ' + cast(@age AS varchar)  
  27.                 when @ids Is not null  
  28.                      then ' and id in (' + @ids +')'  
  29.                 else ' '  
  30.            end  
  31.   
  32. --打印出语句  
  33. select @sql  as '语句'  
  34.   
  35. --执行语句  
  36. --exec(@sql)  
  37. go  
  38.   
  39.   
  40. exec procTest  
  41. /*  
  42. 语句  
  43. select * from #tableTest where 1 = 1   
  44. */  
  45.   
  46. exec procTest '小明',23  
  47. /*  
  48. 语句  
  49. select * from #tableTest where 1 = 1 and name like '小明%'  
  50. */  
  51.   
  52.   
  53. exec procTest @ids = '2,3'  
  54. /*  
  55. 语句  
  56. select * from #tableTest where 1 = 1 and id in (2,3)  
  57. */  


备注:如遇到需多个and参数连接查询,SQL语句可写如下

SET @sql= @sql + 
CASE WHEN @SellerNick <> ''
THEN ' and SellerNick = '+@SellerNick+' '
ELSE '   '
END 

SET @sql= @sql + 
CASE WHEN @LogisticsId <> ''
THEN ' and LogisticsId = '+@LogisticsId+''
  ELSE '   '
END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值