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


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

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

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

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

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


  1. --drop proc proc_test
  2. --go
  3. create proc dbo.proc_test
  4. @in int,
  5. @out int out,
  6. @in_out int output
  7. as
  8. select @out = @in + @in_out, --1 + 2 = 3
  9. @in_out = @out + 1 --3 + 1 = 4
  10. go
  11. declare @in_p int
  12. declare @out_p int
  13. declare @in_out_p int
  14. set @in_p = 1;
  15. set @in_out_p = 2
  16. exec dbo.proc_test @in_p,
  17. @out_p out,
  18. @in_out_p output
  19. select @in_p, --输入参数
  20. @out_p, --输出参数
  21. @in_out_p --输入,输出参数
  22. /*
  23. (无列名) (无列名) (无列名)
  24. 1 3 4
  25. */

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

下面是问题:

  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. create proc procTest
  11. @name varchar(20),
  12. @age int,
  13. @IDs varchar(30)
  14. as
  15. begin
  16. select *from #tableTest where 1=1
  17. end
  18. --当我传入@name参数等于 小明,23岁,还有ID在(1,3)的时候
  19. --我怎么可以弄成可选的参数
  20. --比如,name不为空时候
  21. select *from #tableTest where 1=1 and name like '小明'
  22. --如果name参数为空的时候,IDs参数不为空的时候
  23. select *from #tableTest where 1=1 and id in(1,3)
  24. --请问一下,就有参数不为空的时候存储过程中的SQL追加条件,为空的时候就不追加,这样带可选参数的存储过程怎么写,以及怎么调用,请帮小弟写一个实例
这种问题,本质上就是根据传入的参数不同,进行不同的查询,也就是where 后面的查询条件是动态的。
一般有2中处理方式,一种就是写动态语句,但动态语句由于是动态拼接字符串,所以比较难维护,而且如果存储过程需要执行多次,那么每次都需要重新编译,但每次生成的执行计划,应该是比较优化的。但如果拼接字符串部分,只是少量的话,还是可以用动态语句的,下面我的解法就是用动态语句来实现的,结构清晰,易于维护。
另一种,就是通过在where语句后面写case when来进行判断,这种方法的好处是不用动态拼接语句,但不易于理解,也不易于修改,因为别人不一定能理解你这么写的意思。另一个问题就是性能的问题,因为在原来的公司就用过这种方法,一段时间后,查询非常慢,本来几秒就能出结果,后来几分钟都出不了结果。说实在的,这种方法要求较高的技巧性,也容易出错,不建议使用。
下面是我的解法,用了动态语句来实现,但考虑了维护、测试方面的要求:

  1. --drop table #tableTest
  2. create table #tableTest(id int identity , name varchar(20),age int,)
  3. go
  4. insert into #tableTest
  5. select '小明',23 union all
  6. select '小红',28 union all
  7. select '小军',27
  8. go
  9. select *from #tableTest
  10. go
  11. create proc procTest
  12. @name varchar(20)=null,@age int = null,@IDs varchar(30) = null
  13. as
  14. declare @sql nvarchar(max);
  15. set @sql = '';
  16. set @sql = 'select * from #tableTest where 1 = 1';
  17. set @sql = @sql +
  18. case when @name is not null
  19. then ' and name like ' + QUOTENAME(@name +'%','''')
  20. when @age is not null
  21. then ' and age = ' + cast(@age AS varchar)
  22. when @ids Is not null
  23. then ' and id in (' + @ids +')'
  24. else ' '
  25. end
  26. --打印出语句
  27. select @sql as '语句'
  28. --执行语句
  29. --exec(@sql)
  30. go
  31. exec procTest
  32. /*
  33. 语句
  34. select * from #tableTest where 1 = 1
  35. */
  36. exec procTest '小明',23
  37. /*
  38. 语句
  39. select * from #tableTest where 1 = 1 and name like '小明%'
  40. */
  41. exec procTest @ids = '2,3'
  42. /*
  43. 语句
  44. select * from #tableTest where 1 = 1 and id in (2,3)
  45. */

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

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

  1. 在论坛中出现的比较难的sql问题:46(日期条件出现的奇怪问题)

    原文:在论坛中出现的比较难的sql问题:46(日期条件出现的奇怪问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有 ...

  2. 在论坛中出现的比较难的sql问题:45(用户在线登陆时间的小时、分钟计算问题)

    原文:在论坛中出现的比较难的sql问题:45(用户在线登陆时间的小时.分钟计算问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. ...

  3. 在论坛中出现的比较难的sql问题:44(触发器专题 明细表插入数据时调用主表对应的数据)

    原文:在论坛中出现的比较难的sql问题:44(触发器专题 明细表插入数据时调用主表对应的数据) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决 ...

  4. 在论坛中出现的比较难的sql问题:42(动态行转列 考勤时间动态列)

    原文:在论坛中出现的比较难的sql问题:42(动态行转列 考勤时间动态列) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  5. 在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字)

    原文:在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  6. 在论坛中出现的比较难的sql问题:40(子查询 销售和历史库存)

    原文:在论坛中出现的比较难的sql问题:40(子查询 销售和历史库存) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有 ...

  7. 在论坛中出现的比较难的sql问题:39(动态行转列 动态日期列问题)

    原文:在论坛中出现的比较难的sql问题:39(动态行转列 动态日期列问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉 ...

  8. 在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题)

    原文:在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得 ...

  9. 在论坛中出现的比较难的sql问题:37(动态行转列 某一行数据转为列名)

    原文:在论坛中出现的比较难的sql问题:37(动态行转列 某一行数据转为列名) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  10. 在论坛中出现的比较难的sql问题:36(动态行转列 解析json格式字符串)

    原文:在论坛中出现的比较难的sql问题:36(动态行转列 解析json格式字符串) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

随机推荐

  1. ntpd服务

    yum -y install ntp 服务器端 [root@ip-172-31-6-148~]# vim /etc/ntp.conf ...# Use public servers from thep ...

  2. Activity: launchMode 和 Intent.FLAG_ACTIVITY_CLEAR_TOP

    Activity 的 launchMode: 1. standard: 标准模式 这种启动模式为标准模式,也是默认模式.每当我们启动一个Activity,系统就会相应的创建一个实例,不管这个实例是否已 ...

  3. C/C++如何监测内存泄漏

    C/C++如何监测内存泄漏 C/C++内存泄漏及检测 内存溢出就是内存越界.内存越界有一种很常见的情况是调用栈溢出(即stackoverflow),虽然这种情况可以看成是栈内存不足的一种体现.例如:递 ...

  4. Spring cloud微服务安全实战-6-1本章概述

    这一章来讲一下,微服务之间的通讯安全. 当前这个架构还存在的问题 在网关上做限流还是有一些问题的.例如我的订单服务限流是100,库存服务限流也是100.但是我的订单服务会调用我的库存服务.那么在网关这 ...

  5. 查看所使用的Linux系统是32位还是64 位的方法

    方法一:getconf LONG_BIT # getconf LONG_BIT 1 1 我的Linux是32位!!! 方法二:arch # arch 1 1 显示 i686 就是32位,显示 x86_ ...

  6. k8s记录-dockerfile

    FROM 代表基于哪个镜像 RUN 安装软件使用 MAINTAINER 镜像的创建者 CMD 容器启动时执行的命令,但是一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD EN ...

  7. 123457123456#2#----com.MC.HuiHuaGame33--前拼后广--画画填色Game-mc

    com.MC.HuiHuaGame33--前拼后广--画画填色Game-mc

  8. Spring MVC初始化

      整个Spring MVC的初始化,配置了DispatcherServlet和ContextLoaderListener,那么它们是如何初始化Spring IoC容器上下文和映射请求上下文的呢?所以 ...

  9. Jmeter性能测试实战教程系列-搭建分布式性能测试环境(五)

    Jmeter 是java 应用,对于CPU和内存的消耗比较大,因此,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至会引起JAVA内存溢出错误.为了让jmeter工具 ...

  10. 无限级分类,抓取某元素的所有下级id

    mysql> select id,invite_qke_id from tf_qke; +----+---------------+ | id | invite_qke_id | +----+- ...