首先是存储过程的定义:
CREATE DEFINER=[用户] PROCEDURE [存储过程名] (参数) BEGIN END;
如下图代码:
CREATE DEFINER=`root`@`%` PROCEDURE `NewTest`( )
BEGIN
END
定义了一个名为NewTest的存储过程,它的用户是root,没有任何参数,begin-end之间也没执行任何的操作,但是已经是一个完整的存储过程了。
参数的定义 IN | OUT | INOUT
参数名 类型
IN
传入的参数
OUT
传出的参数
INOUT
传入传出都具备
CREATE DEFINER=`root`@`%` PROCEDURE `NewTest`(
IN `IN_NAME` varchar(200), #传入的参数
OUT `OUI_RETURN` varchar(200) #需要输出的
)
BEGIN
delete from test111 where name=IN_NAME;
if ROW_COUNT()>0 ##ROW_COUNT() mysql 内置的用来返回受影响的行数
then set OUI_RETURN='成功'; #赋值 需要使用set 关键字
else set OUI_RETURN='失败';
end if;
END
这是一个根据传入的姓名进行删除操作,并返回执行结果信息的一个存储过程。有一个传入参数IN_NAME
,和一个传出的参数OUI_RETURN
。
以下为test111的表数据:
call NewTest('徐',@result); ##存储过程的调用 用@result来接收返回值
select @result;##在控制台输出返回的结果
控制台输出结果:
查看一下表 test111,确实已经被删掉了两条name='徐’的数据
通常采用存储过程时都是需要处理复杂的逻辑操作,因此存储过程中必须带有异常回滚和错误信息输出的功能,方便以后的调试。
DECLARE [CONTINUE
|EXIT
] HANDLER FOR [SQLWARNING
|SQLEXCEPTION
|NOT FOUND
] BEGIN [需要执行的操作
] END;
CONTINUE
捕获异常并执行异常操作之后继续执行下面的语句
EXIT
离开最近的一对begin-end
SQLWARNING
SQL警告
SQLEXCEPTION
SQL语句错误
NOT FOUND
没有发现数据 通常与 select into 和游标有关
CREATE DEFINER=`root`@`%` PROCEDURE `NewTest`(
IN `IN_NAME` varchar(200), #传入的参数
OUT `OUI_RETURN` varchar(200) #需要输出的
)
BEGIN
DECLARE r_code varchar(255);#变量的定义 作用域在 包含离它最近的一对 begin-end之间
DECLARE r_msg varchar(255);
##声明异常捕获和捕获后的操作
DECLARE EXIT HANDLER FOR SQLWARNING,SQLEXCEPTION,NOT FOUND ##异常捕获
begin ##出现异常之后 需要执行的操作
GET DIAGNOSTICS CONDITION 1
r_code = RETURNED_SQLSTATE, r_msg = MESSAGE_TEXT; ##将mysql内置的错误代码和错误信息赋值给变量
SET OUI_RETURN =CONCAT('失败',r_code,r_msg); ##CONCAT 字符拼接
end; ## 需要执行的操作结束
delete from test where name=IN_NAME;#删除操作会出现异常,因为没有test这个表
if ROW_COUNT()>0 ##ROW_COUNT() mysql 内置的用来返回受影响的行数
then set OUI_RETURN='成功'; #赋值
else set OUI_RETURN='失败';
end if;
END
由于没有test这张表肯定到删除这个操作的时候会出现SQLEXCEPTION
异常,就会被捕捉到,这时候将会执行异常捕获后的操作将mysql内置的错误信息和错误代码拼接并且赋值给OUI_RETURN
,操作结束之后由于声明的是 EXIT
所以会退出包含它并且离它最近的begin-end,也就是大写的这个BEGIN-END(mysql是不区分大小写的,只是为了方便读者辨认)。
调用一下存储过程,并输出返回值看看是否是这个结果。结果确实显示失败和错误的原因了,原因是没有test这张表
通常查询语句并赋值给变量我们采用 select into语句,但是由于select into只支持一条数据
但有时候我们需要处理结果集,就需要使用游标了,首先也是游标的声明
DECLARE [游标的名称
] cursor for [查询语句
];
当需要打开游标的时候就需要使用open [游标的名字
];
再紧跟loop循环
CREATE DEFINER=`root`@`%` PROCEDURE `NewTest`(
IN `IN_ID` varchar(200)
)
BEGIN
declare r_sql varchar(2000);
declare r_notfound varchar(1);
##该游标是获取test111中的name的值
declare cur_a cursor for select name from test111;
open cur_a;##打开游标
leave_loop:loop ##开启循环,并给循环起个别名叫leave_loop
begin
declare continue handler for not found set r_notfound='Y';##当捕获到没数据的异常时,就置Y
set r_notfound='N';##默认是N
fetch cur_a into r_name; #从游标获取值
if r_notfound='Y' ##如果等于Y 代表没数据
then leave leave_loop;#离开循环
end if;
end;
###下面可以写当有数据时候的各种操作##
end loop;#循环结束
close cur_a;
END
游标取值的顺序必须与定义的时候的顺序相等
1.最常见的想要对mysql存储过程进行调试需要采用select语句,这样运行完毕后就能够在输出台看到r_sql的值。但是如果采用的是Navicat,会发现输出台只能最多显示10个变量的值。
CREATE DEFINER=`root`@`%` PROCEDURE `NewTest`()
BEGIN
declare r_sql varchar(2000);
set r_sql='222';
select r_sql;
END
2.dbForge studio 2020 for mysql
这个软件能够实现如orcal的plsqldev的功能,能够进行一步一步的调试。需要自己寻找资源。如果在调试模式保存后,它会将代码改掉多出一堆用来调试的语句,但是不用担心只要退出调试模式之后再保存一遍就可以变回原来的样子了。还有不要忘记了要在调试之前打好断点,否则一下就运行结束了