<1>一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。存储过程,功能强大,可以执行包括修改表等一系列数据库操作;用户定义函数不能用于执行一组修改全局数据库状态的操作。

<2>对于存储过程来说可以返回参数,如记录集,而函数只能返回值或者表对象。函数只能返回一个变量;而存储过程可以返回多个。存储过程的参数可以有IN,OUT,INOUT三种类型,而函数只能有IN类~~存储过程声明时不需要返回类型,而函数声明时需要描述返回类型,且函数体中必须包含一个有效的RETURN语句。

<3>存储过程,可以使用非确定函数,不允许在用户定义函数主体中内置非确定函数。

<4>存储过程一般是作为一个独立的部分来执行( EXECUTE 语句执行),而函数可以作为查询语句的一个部分来调用(SELECT调用),由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。 SQL语句中不可用存储过程,而可以使用函数。

创建函数:

create Function 函数名([形参列表]) returns 返回值的数据类型
begin
-- 函数体
-- return 返回值
end

实例:

DELIMITER //
 CREATE FUNCTION GetEmployeeInformationByID(id INT)
 RETURNS VARCHAR(300)
 BEGIN
     RETURN(SELECT CONCAT('employee name:',employee_name,'---','salary: ',employee_salary) FROM employees WHERE employee_id=id);
 END//
 DELIMITER ;


创建存储过程:

-- 创建存储过程
DELIMITER $ --声明存储过程的结束符
CREATE PROCEDURE stu_test() --存储过程名称(参数列表)
BEGIN    --开始
    -- 可以写多个sql语句          -- sql语句+流程控制    
END $    --结束 结束符

-- 执行存储过程
call stu_test()   --call 存储过程名称(参数)

参数:
IN:  表示输入参数,可以携带数据带存储过程中
OUT: 表示输出参数,可以从存储过程中返回结果 
INOUT: 表示输入输出参数,两者结合

存储过程例子
-- 1、需求:传入一个学生ID,查询该学生的信息
    -- 带有输入参数的存储过程

delimiter $
 create PROCEDURE stu_findByid(in sid int)
 begin
     select * from student where id=sid;
 END $


-- 调用存储过程

call stu_findByid(1);

-- 2、带有输出参数的存储过程

delimiter $
 create procedure stu_out(out str varchar(20))
 begin


    -- 给参数赋值

set str='这是一个输出参数';
 end $


-- 删除存储过程

drop procedure stu_inout;


-- 调用存储过程
-- 1)定义了一个变量
-- 2)定义了一个会话变量接收存储过程输出的参数

call stu_out(@name);
 select @name;


-- 3、输入输出参数的存储过程

delimiter $
 create procedure stu_inout(inout n int)
 begin
     select n;
     set n=500;
 end $
 set @n=10;
 call stu_inout(@n);
 select @n;

-- 4、带条件判断的存储过程
    -- 需求:输入一个正整数,如果1,返回“星期一”,如果2,返回“星期二。。。。其他返回输入错误”

delimiter $
 create procedure stu_testIf(in num int,out str varchar(20))
 begin
     if num=1 then   -- 开始
         set str='星期一';
     elseif num=2 then
         set str='星期二';
     elseif num=3 then
         set str='星期三';
     else
         set str='输入错误';
     end if;         -- 结束
 end $
 -- 执行存储过程
 call stu_testIf(2,@str);
 select @str;

-- 5、带循环功能的存储过程
    -- 输入一个整数,求和。比如输入100,统计1-100的和

delimiter $
 create procedure stu_testWhile(in num int,out result int)
 begin
         -- 定义两个局部变量
         DECLARE i int default 1;
         declare vsum int default 0;
         while i<=num do
                 set vsum = vsum+i;
                 set i = i+1;
         end while;
         set result = vsum;
 END $
 call stu_testWhile(100,@result);
 select @result;
 drop procedure stu_testWhile;


-- 6、使用查询的结果赋值给变量(into)

delimiter $
 create procedure stu_findByid2(in eid int,out vname varchar(20))
 begin
     select name into vname from student where id=eid;
 end
 call stu_findByid2(1,@vname);
 select @vname;


-- 7、练习,编写一个存储过程

use students;
 select * from user;


    -- 如果学生的英语平均分小于等于70分,刚输出‘一般’
    -- 如果学生的英语平均分大于70,且小于等于90分,刚输出‘良好’
    -- 如果学生的英语平均分大于90分,刚输出‘优秀’

delimiter $
 create procedure stu_testAvg(out str varchar(20))
 begin
     -- 计算英语平均分
     declare savg double;
     select avg(score) into savg from user;
     if savg<=70 then
         set str='一般';
     elseif savg>70 and savg<=90 then
         set str='良好';
     else 
         set str='优秀';
     end if;
 end $
 call stu_testAvg(@str);
 select @str;

mybatis中的使用

<!-- 添加用户 -->
     <insert id="addUser" parameterType="com.po.User" statementType="CALLABLE">
         {call insert_user(
         #{id,mode=OUT,jdbcType=INTEGER},#{name,mode=IN},#{sex,mode=IN},#{age,mode=IN})}
     </insert>