最近项目中较为频繁的使用存储过程,边学边用,有些知识点还颇花费了一些功夫查找,现做些总结。

  一. 这次写的存储过程大多涉及多条件查询的需求,所以大多以此主题为主。看了很多帖子,大多出自同一人之手,多次复制粘贴转发之后已不知原作者,主要有三种写法:

  1.  拼sql:
create proc pro_test 
  
   @param1='' varchar(20),@param2='' varchar(20)           --给参数设置默认值,这样在调用时,不必要的参数就可以不传入

as

declare @sql varchar(1000)='select * from table1 where 1=1 '

if(@param1!='')
   set @sql=@sql+' and name= ''' +@param1 +''''            -- @param两边要用单引号包裹,单引号需要另一个单引号转义
.....  

exec(@sql)

  这种语法灵活性最大,如果条件判断较为复杂,建议采用

   

create proc pro_test 
  
   @param1='' varchar(20),@param2='' varchar(20),@param3 int

as

select * from table1 where  1=1 and
name=case @param1  when '' name else @param1  end and 
gender=ISNULL(@param,param) and                   --sql转换函数
age>CASE WHEN @param3 THEN  10 else 20 END

 

case...when相当于switch .. case语法,可以部分代替if判断语句.这种写法简单,但的局限性比较大,比如对于in(x,y,z),between ... and..就不支持,它只返回单一值

  3.(未实践)

select * from table where (addDate = @addDate or @addDate is null) and (name = @name or @name = '')

 

 

 

    二. 存储过程如果涉及到调用另一个存储过程,也很简单.我在程序中遇到A存储过程要从B存储过程返回的结果集中去查询,

create  proc pro_A 
as
select from exec pro_B

  这样写是错误的,pro_B返回的不是一张表,所以应该先定义一张表,将值注入才行

create  proc pro_A 
as
DECLARE @table TABLE (age INT)         --注意:这里定义的表的列必须与pro_B返回结果集的一致                           
INSERT INTO @table  EXEC pro_B
select * from exec @table

  三.对于有出参的存储过程:入参出参顺序必须一致

CREATE PROC pro_A

     @param1='' varchar(10),
     @num INT OUTPUT                                          
ASSET @num=(SELECT COUNT(1) FROM table1
DECLARE @num INT 
EXEC pro_A @num OUTPUT

这样会报错,因为入参出参顺序的原因,几遍@param有默认值.所以要么改变出参入参定义顺序,要么就把入参带上, EXEC pro_A  'Lily',@num OUTPUT