夜间模式
用户变量
声明一个全局变量在存储过程或者触发器,存储函数中使用
sql
set @name {=|:=} value [,@name2 {=|:=} value....];
value的值可以来这存储函数或者select语句或系统函数
select @name:=value[,@name2=value2...]
#例如
set @pi=3.1415;
select @p=3.1415926;
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
存储过程
当需要大量重复修改、删除、查询数据的时候,一步一步的进行同样的操作实在是太浪费时间和精力,所以有了存储过程和函数。
存储过程是一组为了完成特定功能的sql语句,使用存储过程的目的是将常用或复杂的sql语句写出来,使用的时候直接调用就能达到目的。存储过程有着运行效率高,降低网络通信量的优点,还有着类似封装的优点,用户的规则发生改变时,只需要改变存储过程,不需要修改其他程序,易于维护。
sql
#创建存储过程
create procedure cc_name([in/out/inout 变量名 变量type [in/out/inout 变量名 变量type,...... ] ])
[characteristic ....]#指明存储过程的特性
;
begin
select语句 [#和 流程控制语句]
end;
#in 表示输入参数
#out 表示输出参数
#inout 表示输入输出参数
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
sql
DELIMITER new_end
#设定新的语句结束符
1
2
2
默认结束符为 ;
,避免产生冲突,在创建存储过程前修改结束符,以新设定的结束符结束存储过程,在修改回来存储过程结束符。
sql
DELIMITER ;
1
sql
[characteristic ....]#指明存储过程的特性
create procedure ccgc_name(in a char(10),out b varchar(20),inout c int(20))
language sql #指明存储过程由sql组成
[not] deterministic #确认执行的结果是否确认,默认not deterministic 即输入相同的值,是否输出相同的值,有not是不确定输出的值相同
contains sql/// no sql ///read sql data///modifies sql data
#表示sql语言的限制,1.包含sql,不包含读写sql语句,2表示不包含sql语句,3表示包含读sql语句,4表示包含写sql的语句 默认1
sql security {definer|invoker}指明存储过程的许可是用户(1)还是调用者(2),默认1
comment 'string'#注释
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
显示存储过程
sql
show create procedure cc_name;
1
显示存储过程状态
sql
show procedure status like cc_name;
1
删除存储过程
sql
DROP PROCEDURE [if exists] cc_name;#if exists 防止删除不存在的存储过程出现错误
1
修改存储过程的特性
sql
ALTER procedure cc_name [characteristic...];
1
使用存储过程
sql
call cc_name([字段1,字段2.....])
1
sql
DECLARE var_name[,....] type [DEFAULE value]
1
==DECLARE==声明局部变量
var_name 指定变量名
type 指定变量类型
DEFAULT语句,指定默认初始值,未指定默认NULL
局部函数仅在begin....end中使用,必须在存储过程开头声明,命名不需要@开头
sql
#赋值语句
set var_name=value[,var_name2=value2....]
value和用户变量一样可以是多种形式
select 字段1[,字段2...] into var_name1[,var_name2....] table_name [where 筛选语句];
#例如
declare p_name varchar(20);
select table_字段 into p_name from table_name where table_id=8;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
执行完一句selecte....into 语句只返回一行数据,可以很好的被存储函数处理 。但运用select语句的时候,返回的是一组数据集合,这个数据集合可能拥有多行数据,这些数据不能很好的被处理,人们为了处理这个情况,创建了游标这个概念,使用游标,根据需要滚动或者浏览其中的数据。游标是一个被select检索出来的数据集。
游标只能运用于存储过程和存储函数中,不能单独的在查询操作中使用。
每个存储过程或存储函数可以拥有多个游标,但 每个游标的名字不能相同
游标是一个被select检索出来的数据集,并不是一个select语句。
声明游标
sql
DECLARE 游标name CURSOR FOR select语句
#例如
declare stu_name_and_age cursor for select name,age from students;
1
2
3
2
3
打开游标
在使用游标前,需要打开游标,实际是将游标连接到select返回的结果集中语法如下
sql
open 游标name;
#例如
open stu_name_and_age;
1
2
3
2
3
每次打开游标的时候,由于用户或者应用程序更新了数据,每次打开游标的时候可能会改变结果集
读取数据
sql
FETCH 游标name INTO 字段1[,字段2....]
#例如
fetch stu_name_and_age into name,age;
#打开游标的时候的变量数目与类型必须与声明游标的选择列数相同
#游标相当于一个指针,指向当行的数据
1
2
3
4
5
2
3
4
5
关闭游标
sql
CLOSE 游标name;
1
结束使用游标时,必须关闭游标。再次使用不用重新打开,若未关闭游标,在end时mysql会自动关闭
流程控制
sql
IF 判断语句 THEN
select语句
[ELSEIF [判断语句] select语句]
[ELSE select语句]
END IF;
#例如
set @a=1;
IF @a=1 THEN
@a=@a+1
select * from students;
ELSE select * classes;
END IF;
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
sql里面的if语句不像c/c++用括号控制语句也不想python用缩进来判断结束,而是用了一个结束符 END来判断IF语句是否结束.
sql
CASE case_value #表示判断的值或表达式##类似switch...case
WHEN 判断1 THEN select语句 ;
[WHEN 判断2 THEN select语句 ;]
[.....]
[ELSE select语句 ;]#若每次结果都不对则执行这段语句
END CASE ;
#例如
CASE var
when 1 select '1';
when 2 select '2';
else select '都不是'
END CASE;
CASE 的另外一种表达形式
CASE
WHEN 判断语句或表达式 THEN SELECT语句;
[ WHEN 判断语句或表达式 THEN SELECT语句;]
ELSE select语句;
END CASE;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
存储过程case语句中不能有else null子句,用end case替代end表示终止.
sql
[begin_label:] while 判断语句 DO
select语句+流程过程
END while [end_label]
#[begin_label:]和[end_label]是while循环的标注,名字必须相同并成对出现。相当于给循环起名
1
2
3
4
2
3
4
mysql
[begin_label:] REPEAT select语句+流程过程
UNTIL 判断语句
END REPEAT [end_label];#类似while和do...while的区别repeat循环会先执行后判断,while会先判断后执行。
1
2
3
2
3
loop循环与其他循环不一样的是没有判断退出循环的语句。
sql
[begin_label:] LOOP
select语句+流程过程
END LOOP [end_label];
1
2
3
2
3
你以为没有条件判断会直接死循环吗?不可能!
学过c/c++或者python或者java的都知道循环语句中会有break;和continue;语句,那么
==LEAVE==
sql
LEAVE label;
#类似 break label;
1
2
2
label是循环语句的标识,举例
sql
this_xunhuan: LOOP
DECLARE i int DEFAULT 0;
set i=i+1;
if i=100 then leave this_xunhuan;
end if;
end loop this_xunhuan;
1
2
3
4
5
6
2
3
4
5
6
当i循环加到了100的时候就通过label退出了循环.ps:在while循环和REPEAT循环中也可以使用LEAVE和下面的ITERTE;
==ITERATE==
既然LEAVE是break;那么ITERTE 就是continue;
sql
iterate label_name;
1
作用与continue一样,有着跳出当前循环,进入下一循环的 作用
sql
this_xunhuan: LOOP
DECLARE i int DEFAULT 0;
set i=i+2;
if i=50 then set i=i+20;
iterate this_xunhuan;
if i=70 then leave this_xunhuan;
end if;
end loop this_xunhuan;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
当i到了50的时候,加到了70,执行了iterate语句跳到下一个循环又加了2变成了72,所以这个循环变成了死循环。