一、mysql存储过程
1、什么是存储过程?
存储过程是一组为了完成特定功能的 SQL 语句集合(比如从1加到100的功能实现)。它类似于方法,就是一个封装sql语言的一个没有返回值的方法。调用时用“CALL存储过程名字”即可。
存储过程就是具有名字的一段代码,用来完成一个特定的功能。
2、为什么是用它?直接sql语句不香吗?
前面说了,存储过程就像开发语言中的函数(mysql中的函数必须有返回值),这就好比面向对象编程和面向过程编程的区别,体现封装的重要性,相对复杂的逻辑处理,避免重复造轮子。
3、存储过程的特点
优点:
1、能完成较复杂的判断和运算
2、可编程行强,灵活
3、SQL编程的代码可重复使用
4、执行的速度相对快一些
5、减少网络之间的数据传输,节省开销
缺点:
1、编写比SQL语句复杂
2、性能调校与撰写,受限于各种数据库系统
3、移植性很差,切换数据库时,需要重新编写
3、创建一个简单的存储过程
3.1 基础语法
其中 $$ 可以替换成 //
-- 判断如果存在则删除,可以根据实际情况选择使用
drop procedure if exists `存储过程名称`;
-- 创建存储过程
delimiter $$
create procedure 存储过程名称()
begin
//具体sql语句
end $$
-- 调用存储过程
call 存储过程名称();
3.2 创建一个简单的存储过程
-- 判断如果存在则删除,可以根据实际情况选择使用
drop procedure if exists `test`;
-- 创建存储过程
delimiter $$
create procedure test()
begin
select 'joker say hello world';
end $$
-- 调用存储过程
call test();
4、变量
4.1 什么是变量?
变量是一个命名数据对象,变量的值可以在存储过程执行期间更改。我们通常使用存储过程中的变量来保存直接/间接结果。 这些变量是存储过程的本地变量。
变量必须先声明后,才能使用它。
1、先通过一个简单的例子来学习变量的声明和赋值
create procedure test2()
begin
-- 使用 declare语句声明一个变量
declare username varchar(32) default '';
-- 使用set语句给变量赋值
set username='xiaoxiao';
-- 将users表中id=1的名称赋值给username
select name into username from users where id=1;
-- 返回变量
select username;
end;
2、概括
(1)、delimiter // 告诉命令行实用程序使用 // 作为新的语句结束分隔符
(2)、变量的声明使用declare,一句declare只声明一个变量,变量必须先声明后使用;
(3)、变量具有数据类型和长度,与mysql的SQL数据类型保持一致,因此甚至还能制定默认值、字符集和排序规则等;
(4)、变量可以通过set来赋值,也可以通过select into的方式赋值;
(5)、变量需要返回,可以使用select语句,如:select 变量名。
注:查询可以使用游标获取单个或一组数据,但有时候返回值就只有一个,那么我们通常使用查询(SELECT ...INTO ...FROM )赋值方法.
第二种方法:使用SELECT …INTO语句为变量赋值
在MySQL存储过程中,可以使用SELECT …INTO语句对变量进行赋值,该语句在数据库中进行查询,并将得到的结果赋值给变量。SELECT …INTO语句的语法格式如下:
SELECT col_name[,...] INTO var_name[,...] table_expr
col_name:要从数据库中查询的列字段名;
var_name:变量名,列字段名按照在列清单和变量清单中的位置对应,将查询得到的值赋给对应位置的变量;
table_expr:SELECT语句中的其余部分,包括可选的FROM子句和WHERE子句。
需要注意的是,在使用SELECT …INTO语句时,变量名不能和数据表中的字段名不能相同,否则会出错。范例语句:
create procedure getMsg () Begin declare v_title varchar(30); declare v_content varchar(100); select title,content into v_title,v_content from news where artId=333; End
将变量值返回给调用者
在存储过程中定义的变量,经过一系列的处理之后,结果值可能需要返回给存储过程调用者。那么如何返回呢?方便的做法是使用SELECT语句将变量作为结果集返回,因此,在上面一段代码的基础上,加上一句:
create procedure getMsg () Begin declare v_title varchar(30); declare v_content varchar(100); select title,content into v_title,v_content from news where artId=333; select v_title,v_content; End
4.2 变量的作用域
如果在存储过程中声明一个变量,那么当达到存储过程的END
语句时,它将超出范围,因此在其它代码块中无法访问。
简单理解就是,作用范围在begin和end块之间,超过end就会失效。
-- 创建存储过程
delimiter $$
create procedure test3()
begin
-- 定义一个 年龄变量
DECLARE age int DEFAULT 0;
begin
set age = 18;
end;
begin
-- 查询年龄变量
select age;
end;
end $$
-- 调用存储过程
call test3();
5、参数
在现实应用中,开发的存储过程几乎都需要参数。这些参数使存储过程更加灵活和有用。 在MySQL中,参数有三种模式:IN,OUT或INOUT。
IN 输入参数(默认模式--(代表输入,意思说你的参数要传到存过过程的过程里面去)):表示该参数的值必须在调用存储过程时指定赋值,在存储过程中修改该参数的值不能被返回,为默认值
OUT 输出参数 (代表往外输出):该值可在存储过程内部被改变,并可返回
INOUT 输入输出参数(既能输入一个值又能传出来一个值):调用时必须指定具体值,并且可在存储过程体重被改变和在调用完毕后可被返回
6、存储过程条件语句
1、基本结构
(1)、条件语句基本结构:
if() then...else...end if;
(2)、多条件判断语句:
-
if() then...
-
elseif() then...
-
else ...
-
end if;
2、实例
实例1:编写存储过程,如果用户userId是偶数则返回username,否则返回userId
create procedure test7(in userId int)
begin
declare username varchar(32) default '';
if(userId%2=0)
then
select name into username from users where id=userId;
select username;
else
select userId;
end if;
end;
2、存储过程的多条件语句应用示例
需求:根据用户传入的uid参数判断
(1)、如果用户状态status为1,则给用户score加10分;
(2)、 如果用户状态status为2,则给用户score加20分;
(3)、 其他情况加30分
create procedure test8(in userid int)
begin
declare my_status int default 0;
select status into my_status from users where id=userid;
if(my_status=1)
then
update users set score=score+10 where id=userid;
elseif(my_status=2)
then
update users set score=score+20 where id=userid;
else
update users set score=score+30 where id=userid;
end if;
end;
7、存储过程循环语句
1、while语句
while/do相当于 Java的while do
(1)、while语句的基本结构
-
while(表达式) do
-
......
-
end while;
(2)、示例
需求:使用循环语句,向表test1(id)中插入10条连续的记录
create procedure test9()
begin
declare i int default 0;
while(i<10) do
begin
select i;
set i=i+1;
insert into test1(id) values(i);
end;
end while;
end;
2、repeat语句
repeat/util 相当于 Java的do while
(1)、repeat语句基本的结构:
repeat...until...end repeat;
(2)、示例
需求:给test1表中的id字段插入数据,从1到10
create procedure test10()
begin
declare i int default 0;
repeat
begin
select i;
set i=i+1;
insert into test1(id) values(i);
end;
until i>=10 -- 如果i>=10,则跳出循环
end repeat;
end;
概括:
until判断返回逻辑真或者假,表达式可以是任意返回真或者假的表达式,只有当until语句为真是,循环结束。
8、存储过程游标的使用
1、什么是游标
游标是保存查询结果的临时区域
2、示例
需求:编写存储过程,使用游标,把users表中 id为偶数的记录逐一更新用户名
create procedure test11()
begin
declare stopflag int default 0;
declare username VARCHAR(32);
-- 创建一个游标变量,declare 变量名 cursor ...
declare username_cur cursor for select name from users where id%2=0;
-- 游标是保存查询结果的临时区域
-- 游标变量username_cur保存了查询的临时结果,实际上就是结果集
-- 当游标变量中保存的结果都查询一遍(遍历),到达结尾,将变量stopflag设置为1,用于循环中判断是否结束
declare continue handler for not found set stopflag=1;
open username_cur; -- 打卡游标
fetch username_cur into username; -- 游标向前走一步,取出一条记录放到变量username中
while(stopflag=0) do -- 如果游标还没有结尾,就继续
begin
-- 在用户名前门拼接 '_cur' 字符串
update users set name=CONCAT(username,'_cur') where name=username;
fetch username_cur into username;
end;
end while; -- 结束循环
close username_cur; -- 关闭游标
end;
9、自定义函数
函数与存储过程最大的区别是函数必须有返回值,否则会报错
1、一个简单的函数
create function getusername(userid int) returns varchar(32)
reads sql data -- 从数据库中读取数据,但不修改数据
begin
declare username varchar(32) default '';
select name into username from users where id=userid;
return username;
end;
概括:
1.创建函数使用create function 函数名(参数) returns 返回类型;
2.函数体放在begin和end之间;
3.returns指定函数的返回值;
4.函数调用使用select getusername()。
2、示例
需求:根据userid,获取accoutid,id,name组合成UUID作为用户的唯一标识
create function getuuid(userid int) returns varchar(64)
reads sql data -- 从数据库中读取数据,但不修改数据
begin
declare uuid varchar(64) default '';
select concat(accontid,'_',id,'_',name) into uuid from users where id=userid;
return uuid;
end;
10、触发器
1、什么是触发器
触发器与函数、存储过程一样,触发器是一种对象,它能根据对表的操作时间,触发一些动作,这些动作可以是insert,update,delete等修改操作。
2、示例1
(1)、需求:出于审计目的,当有人往表users插入一条记录时,把插入的userid,username,插入动作和操作时间记录下来。
create trigger tr_users_insert after insert on users
for each row
begin
insert into oplog(userid,username,action,optime)
values(NEW.id,NEW.name,'insert',now());
end;
创建成功后,给uses表中插入一条记录:
-
insert into users(id,name,age,status,score,accontid)
-
values(6,'小周',23,1,'60','10001');
(2)、总结
1、创建触发器使用create trigger 触发器名
2、什么时候触发?after insert on users,除了after还有before,是在对表操作之前(before)或者之后(after)触发动作的。
3、对什么操作事件触发? after insert on users,操作事件包括insert,update,delete等修改操作;
4、对什么表触发? after insert on users
5、影响的范围?for each row
3、示例2
需求:出于审计目的,当删除users表时,记录删除前该记录的主要字段值
create trigger tr_users_delete before delete on users
for each row
begin
insert into oplog(userid,username,action,optime)
values(OLD.id,OLD.name,'delete',now());
end;
删除users表中的一条记录
delete from users where id=6;
11、流程控制
1、case分支
(1)、基本语法结构
case ...
when ... then....
when.... then....
else ...
end case;
(2)、示例
users表中,根据userid获取status值,如果status为1,则修改score为10;如果status为2,则修改为20,如果status3,则修改为30;否则修改为40。
create procedure testcate(userid int)
begin
declare my_status int default 0;
select status into my_status from users where id=userid;
case my_status
when 1 then update users set score=10 where id=userid;
when 2 then update users set score=20 where id=userid;
when 3 then update users set score=30 where id=userid;
else update users set score=40 where id=userid;
end case;
end;
12、存储过程+event(事件)
1、使用存储过程+事件事件一个简单的实现福彩3D开奖
需求:设计一个福彩的开奖过程,没3分钟开奖一次
第一步:先编写一个存储过程open_lottery,产生3个随机数,生成一条开奖记录
第二步:编写一个时间调度器,每3分钟调用一次这个过程
create procedure open_lottery()
begin
insert into lottery(num1,num2,num3,ctime)
select FLOOR(rand()*9)+1,FLOOR(rand()*9)+1,FLOOR(rand()*9)+1,now();
end;
create event if not exists lottery_event -- 创建一个事件
on schedule every 3 minute -- on schedule 什么时候来执行,没三分钟执行一次
on completion preserve
do call open_lottery;
注意,如果event之一没有运行,请按照以下办法解决:
(1)、 show variables like '%event_scheduler%';
set global event_scheduler=on;
(2)、 alert event lottery_event enable;
2、解析event的创建格式
(1)、基本语法
create event[IF NOT EXISTS]event_name -- 创建使用create event
ON SCHEDULE schedule -- on schedule 什么时候来执行
[ON COMPLETION [NOT] PRESERVE] -- 调度计划执行完成后是否还保留
[ENABLE | DISABLE] -- 是否开启事件,默认开启
[COMMENT 'comment'] -- 事件的注释
DO sql_statement; -- 这个调度计划要做什么?
(2)、执行时间说明
1.单次计划任务示例
在2019年2月1日4点执行一次
on schedule at '2019-02-01 04:00:00'
2. 重复计划执行
on schedule every 1 second 每秒执行一次
on schedule every 1 minute 每分钟执行一次
on schedule every 1 day 没天执行一次
3.指定时间范围的重复计划任务
每天在20:00:00执行一次
on schedule every 1 day starts '2019-02-01 20:00:00'
二、mysql存储函数
存储函数和存储过程一样,都是在数据库中定义一些 SQL 语句的集合。存储函数可以通过 return 语句返回函数值,主要用于计算并返回一个值。而存储过程没有直接返回值,主要用于执行操作。
1.什么是存储函数: 封装一段sql代码,完成一种特定的功能,返回结果。
MySQL存储函数(自定义函数),函数一般用于计算和返回一个值,可以将经常需要使用的计算或功能写成一个函数。
2.存储函数的语法:
create function 函数([函数参数[,….]]) Returns 返回类型
Begin
If(
Return (返回的数据)
Else
Return (返回的数据)
end if;
end;
参数说明:
(1)func_name :存储函数的名称。
(2)param_name type:可选项,指定存储函数的参数。type参数用于指定存储函数的参数类型,该类型可以是MySQL数据库中所有支持的类型。
(3)RETURNS type:指定返回值的类型。
(4)characteristic:可选项,指定存储函数的特性。
(5)routine_body:SQL代码内容。
示例:在数据库中mysql_test中创建一个存储函数,要求该函数能根据给定的客户id号返回客户的性别,如果数据库中没有给定的客户id号,则返回"没有该客户". 用例表:customer(cust_id,cust_sex,cust_name); ->use mysql_test; ->delimiter $$ ->create function fn_name(cid int) //创建一个存储函数,题目要求我们输入id号判断性别,所以是int -> returns char(2) //返回性别,所以char类型 -> deterministic //为了提高where子句的性能加的 ->begin //接下来要写函数体了 -> declare sex char(2); //声明局部变量用来装性别 -> select cust_sex into sex from customer //把这个性别放进局部变量 -> where cust_id = cid; //判断id相符 -> if sex is null then //判断这个局部变量性别对应的属性 -> return(select '没有该客户'); -> else if sex = '女' then -> return(select "女"); -> else return(select "男"); -> end if; //用来结束else if的语句 -> end if; //用来结束if的语句 ->end $$ //用来结束存储函数
MYSQL 存储过程中的关键语法
声明语句结束符,可以自定义:
DELIMITER $$ 或 DELIMITER //
声明存储过程:
CREATE PROCEDURE demo_in_parameter(IN p_in int)
存储过程开始和结束符号:
BEGIN .... END
变量赋值:
SET @p_in=1
变量定义:
DECLARE l_int int unsigned default 4000000;
创建mysql存储过程、存储函数:
create procedure 存储过程名(参数)
存储过程体:
create function 存储函数名(参数)
3、调用存储函数
在MySQL中,存储函数的使用方法与MySQL内部函数的使用方法基本相同。用户自定义的存储函数与MySQL内部函数性质相同。区别在于,存储函数是用户自定义的。而内部函数由MySQL自带。其语法结构如下:
SELECT func_name([parameter[,…]]);
4、修改存储函数
MySQL中,通过ALTER FUNCTION 语句来修改存储函数,其语法格式如下:
ALTER FUNCTION func_name [characteristic ...]
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
5、删除存储函数
MySQL中使用DROP FUNCTION语句来删除存储函数。
示例:删除存储函数。
DROP FUNCTION IF EXISTS func_user;
三、mysql存储过程与存储函数的区别
怎么查询,怎样写sql
在sql 语句中判断不能用 == ,要用 = 就行了 ,赋值 用 :=
函数 和 储存过程的相同点 和不同点:
函数的创建:
函数只能在指定数据库中用。 和存储方法一样
delimiter
createfunction函数名称(参数列表)returns返回类型beginsql语句end
createfunction函数名称(参数列表)returns返回类型beginsql语句end
delimiter ;
调用:
select 函数名(参数列表)
删除函数:
drop function 函数名称;
储存过程的创建:
delimiter //
create procedure 存储过程名称(参数列表)
begin
sql语句
end
//
delimiter ;
调用时:
call 储存过程名(); --没有参数的话括号可以省去
删除储存过程:
drop procedure 存储过程名称;
相同点
提高了语法的执行效率
* 存储过程和函数都是为了可重复的执行操作数据库的 sql 语句的集合.
* 存储过程和函数都是一次编译,就会被缓存起来,下次使用就直接命中缓存中已经编译好的 sql, 不需要重复编译
* 减少网络交互,减少网络访问流量
不同点
* 标识符不同,函数的标识符是 function, 过程:procedure
* 函数中有返回值,且必须有返回值,而过程没有返回值,但是可以通过设置参数类型(in,out)来实现多个参数或者返回值
* 函数使用 select 调用,存储过程需要使用 call 调用
* select 语句可以在存储过中调用,但是除了 select ... into 之外的 select 语句都不能再函数中调用
* 通过 in out 参数,过程相关函数更加灵活,可以返回多个结果
* 在实际开发中根据个人喜好选择使用函数或者存储过程
1、存储过程实现的功能要复杂一点,函数实现的功能针对性比较强。
存储过程,功能强大,可以执行包括修改表等一系列数据库操作;
用户定义函数不能用于执行一组修改全局数据库状态的操作。
2、对于存储过程来说可以返回参数,如记录集,函数只能返回值或者表对象。
函数只能返回一个变量;而存储过程可以返回多个;
存储过程的参数可以有IN,OUT,INOUT三种类型,而函数只能有IN类;
存储过程声明时不需要返回类型,而函数声明时需要描述返回类型,且函数体中必须包含一个有效的RETURN语句。
3、存储过程,可以使用非确定函数,不允许在用户定义函数主体中内置非确定函数。
4、存储过程一般是作为一个独立的部分来执行( EXECUTE 语句执行),而函数可以作为查询语句的一个部分来调用(SELECT调用)。
由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。 SQL语句中不可用存储过程,而可以使用函数。
5、函数必须指定返回值,且参数默认为IN类型。
6、调用方式:函数 select my_fun() ;过程 call my_pro( ) ;
查看
* 所有存储过程和函数,都存储在mysql数据库下的proc表中
* 查看表结构
desc mysql.proc\G;
* 主要字段说明:
*
* name表示名称
* type表示类型,为存储过程、函数
* body表示正文脚本
* db表示属于的数据库
* 查看python数据库的所有存储过程
select name,type,body from mysql.proc where db='python';
函数实例:
-- 输出 0 ~ 100 间的偶数
-- 递增某一个值
-- 判断该值是否为偶数
-- 将偶数 拼接成一个字符串 最后返回
delimiter //
create function f3() returns varchar(300)
begin
-- 1. 声明递增的值 i, 拼接结果的 res
declare i int default 0;
declare res varchar(300) default '';
-- 2. 通过 while 递增 i
while i <= 100 do
-- 3. 判断 i 是否是偶数
if i % 2 = 0 then
-- 4. 拼接偶数
set res = concat(res,' ',i);
end if;
-- 递增 i
set i = i + 1;
end while;
-- 5. 返回 res
return res;
end
//
delimiter ;
储存过程实例:
-- 传入一个英雄的 id 删除该英雄,并且返回剩下的英雄总人数
delimiter //
create procedure deleteherobyid_getcount(in hid int unsigned,out rescount int)
begin
delete from mm_users where id = hid;
select count(*) from mm_users into rescount;
end
//
delimiter ;
四、触发器
1、什么是触发器?
触发器的概念,就是你执行一条sql语句,这条sql语句的执行会自动去触发执行其他的sql语句,就这么简单。
超简说明:sql1->触发->sqlN,一条sql触发多个sql。
触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。
触发器的特性:
1、有begin end体,begin end;之间的语句可以写的简单或者复杂
2、什么条件会触发:I、D、U
3、什么时候触发:在增删改前或者后
4、触发频率:针对每一行执行
5、触发器定义在表上,附着在表上。
也就是由事件来触发某个操作,事件包括INSERT语句,UPDATE语句和DELETE语句;可以协助应用在数据库端确保数据的完整性。
注意:cannot associate a trigger with a TEMPORARY table or a view.
!!尽量少使用触发器,不建议使用。
假设触发器触发每次执行1s,insert table 500条数据,那么就需要触发500次触发器,光是触发器执行的时间就花费了500s,而insert 500条数据一共是1s,那么这个insert的效率就非常低了。因此我们特别需要注意的一点是触发器的begin end;之间的语句的执行效率一定要高,资源消耗要小。
触发器尽量少的使用,因为不管如何,它还是很消耗资源,如果使用的话要谨慎的使用,确定它是非常高效的:触发器是针对每一行的;对增删改非常频繁的表上切记不要使用触发器,因为它会非常消耗资源。
2、触发器创建的四个要素
(1)监视地点(table)
(2)监视事件(insert/update/delete)
(3)触发时间(after/before)
(4)触发事件(insert/update/delete)
3、创建触发器
- delimiter 自定义结束符号
- create trigger triggerName
- after/before insert/update/delete on 表名
- for each row #这句话在mysql是固定的 (也就是create trigger 触发器名字 触发时间 触发事件 on 表 for each row)
- begin
- sql语句;
- end;
- delimiter ;
on 表 for each
:触发对象,触发器绑定的实质是表中的所有行,因此当每一行发生指定改变时,触发器就会发生。
trigger_name
: 触发器名称,用户自行指定trigger_time
: 触发时机,取值BEFORE(之前)、AFTER(之后)trigger_event
: 出发事件,INSERT、UPDATE、DELETE。(插入、更新、删除)tbl_name
: 需要建立触发器的表名。trigger_stmt
: 触发程序体,可以是一条SQL语句或是BEGIN和END包含的索条语句
- 由上面,可以知道MYSQL可以创建6种类型的触发器。
(BEFORE INSERT、BEFORE UPDATE、BEFORE DELETE)
(AFTER INSERT、AFTER UODATE、AFTER DELETE) - 并且一张表上不能创建两个相同类型的触发器,因此一张表上面最多能创建6种类型的触发器。
-
trigger_event详解
INSERT
型触发器 :插入某一行时激活触发器,可能INSERT、LOAD DATA、REPLACE语句触发。UPDATE
型触发器 : 更改某一行时激活触发器,可能通过UPDATE语句触发。DELETE
型触发器 : 删除某一行时激活触发器,可能通过DELETE、REPLACE语句触发。
4、查看触发器
语法:show triggers;
语法:show create trigger 触发器名字;
我们来查看刚才创建的触发器
5、删除触发器
触发器不能修改,只能删除
语法:drop trigger + 触发器名字
五、游标
例子:
当前有三张表A、B、C其中A和B是一对多关系,B和C是一对多关系,现在需要将B中A表的主键存到C中;
常规思路就是将B中查询出来然后通过一个update语句来更新C表就可以了,但是B表中有2000多条数据,
难道要执行2000多次?显然是不现实的;最终找到写一个存储过程然后通过循环来更新C表,
然而存储过程中的写法用的就是游标的形式。
1、定义游标:
游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。
游标充当指针的作用。
尽管游标能遍历结果中的所有行,但他一次只指向一行。
游标的作用就是用于对查询数据库所返回的记录进行遍历,以便进行相应的操作。
注意:MySQL 中的游标只能用于存储过程和函数。
游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。
2、创建游标:
- 1.定义游标:declare 游标名 cursor for select语句;
- 2.打开游标:open 游标名;
- 3.获取结果:fetch 游标名 into 变量名[,变量名];
- 4.关闭游标:close 游标名;
注:mysql存储过程每一句后面必须用;结尾,使用的临时字段需要在定义游标之前进行声明。
游标(cursor)必须在声明处理程序之前被声明,并且变量和条件必须在声明游标或处理程序之前被声明。
create procedure p2() begin declare id int; declare name varchar(15); -- 声明游标 declare mc cursor for select * from class; -- 打开游标 open mc; -- 获取结果 loop -- 循环,将表的内容都转移到class2中 fetch mc into id,name; -- 这里是为了显示获取结果 insert into class2 values(id,name); -- 关闭游标 end loop; close mc; end;
3、使用游标:
- 游标每一次fetch都是获取一行结果,可以使用变量来获取fetch到的每一列的值