在论坛中出现的比较难的sql问题:14(存储过程问题 存储过程参数、存储过程内的参数)

蹲街弑〆低调 提交于 2019-12-11 00:17:56
原文:在论坛中出现的比较难的sql问题:14(存储过程问题 存储过程参数、存储过程内的参数)

最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。

所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。


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

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

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

--drop proc proc_test--go  create proc dbo.proc_test@in int,@out int out,@in_out int outputas select @out = @in + @in_out,  --1 + 2 = 3       @in_out = @out + 1     --3 + 1 = 4go  declare @in_p intdeclare @out_p intdeclare @in_out_p int set @in_p = 1;set @in_out_p = 2 exec dbo.proc_test @in_p,                   @out_p out,                   @in_out_p output                    select @in_p,    --输入参数       @out_p,   --输出参数       @in_out_p --输入,输出参数/*(无列名)	(无列名)	(无列名)1	3	4*/       

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

下面是问题:
create table #tableTest(id int identity , name varchar(20),age int,)goinsert into #tableTestselect '小明',23 union allselect '小红',28 union allselect '小军',27goselect *from #tableTestgo  create proc procTest@name varchar(20),@age int,@IDs varchar(30)asbeginselect *from #tableTest where 1=1end --当我传入@name参数等于 小明,23岁,还有ID在(1,3)的时候--我怎么可以弄成可选的参数--比如,name不为空时候select *from #tableTest where 1=1 and name like '小明'--如果name参数为空的时候,IDs参数不为空的时候select *from #tableTest where 1=1 and id in(1,3)--请问一下,就有参数不为空的时候存储过程中的SQL追加条件,为空的时候就不追加,这样带可选参数的存储过程怎么写,以及怎么调用,请帮小弟写一个实例
这种问题,本质上就是根据传入的参数不同,进行不同的查询,也就是where 后面的查询条件是动态的。
一般有2中处理方式,一种就是写动态语句,但动态语句由于是动态拼接字符串,所以比较难维护,而且如果存储过程需要执行多次,那么每次都需要重新编译,但每次生成的执行计划,应该是比较优化的。但如果拼接字符串部分,只是少量的话,还是可以用动态语句的,下面我的解法就是用动态语句来实现的,结构清晰,易于维护。
另一种,就是通过在where语句后面写case when来进行判断,这种方法的好处是不用动态拼接语句,但不易于理解,也不易于修改,因为别人不一定能理解你这么写的意思。另一个问题就是性能的问题,因为在原来的公司就用过这种方法,一段时间后,查询非常慢,本来几秒就能出结果,后来几分钟都出不了结果。说实在的,这种方法要求较高的技巧性,也容易出错,不建议使用。
下面是我的解法,用了动态语句来实现,但考虑了维护、测试方面的要求:
--drop table #tableTest create table #tableTest(id int identity , name varchar(20),age int,)goinsert into #tableTestselect '小明',23 union allselect '小红',28 union allselect '小军',27goselect *from #tableTestgo create proc procTest@name varchar(20)=null,@age int = null,@IDs varchar(30) = nullas declare @sql nvarchar(max);set @sql = ''; set @sql = 'select * from #tableTest where 1 = 1'; set @sql = @sql +            case when @name is not null                     then ' and name like ' + QUOTENAME(@name +'%','''')                when @age is not null                     then ' and age = ' + cast(@age AS varchar)                when @ids Is not null                     then ' and id in (' + @ids +')'                else ' '           end --打印出语句select @sql  as '语句' --执行语句--exec(@sql)go  exec procTest/*语句select * from #tableTest where 1 = 1 */ exec procTest '小明',23/*语句select * from #tableTest where 1 = 1 and name like '小明%'*/  exec procTest @ids = '2,3'/*语句select * from #tableTest where 1 = 1 and id in (2,3)*/

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!