MySQL知识点
基础
MySQL在Linux下的安装配置
# 下载数据库
sudo apt-get install mysql-server-8.0
# 登录mysql并修改密码
mysql -uroot
mysql> use mysql;
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
mysql>flush privileges;
mysql> quit;
# 再次登录时需要需要输入密码
mysql -uroot -p
-
开启数据库远程连接
mysql>use mysql; mysql>update user set host="%"where user="root"; mysql>flush privileges; mysql> quit;
其中host后面接的是主机IP,设置为通配符%表示所有的主机都可以连接。
-
开放数据库端口
# 查看端口的状态 netstat -an | grep 3306
vim /etc/mysql/mysql.conf.d/mysqld.cnf
打开该文件后注释掉下面这行:
bind-address = 127.0.0.1
重启mysql
/etc/init.d/mysql restart
SQL
通用语法及分类
-
SQL通用语法
- SQL语句可与i单行活多行书写,以分号结尾
- SQL语句可以使用空格/缩进来增强语句的可读性
- MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。
- 注释:
- 单行注释:-- 注释内容 或 #注释内容
- 多行注释:/* 注释内容*/
-
SQL分类
分类 全称 说明 DDL Data Definition Language 数据定义语言,用来定义数据库对象(数据库,表,字段) DML Data Manipulation Language 数据操作语言,用来对数据库中表的数据进行增删改 DQL Data Query Language 数据查询语言,用来查询数据库中的表记录 DCL Data Control Language 数据控制语言,用来创建数据库用户,控制数据库的访问权限
DDL数据库操作
-
查询
查询所有数据库
show databases;
查询当前数据库
select DATABASE();
-
创建
creat database [if not exists] 数据库名 [default charset 字符集][collate 排序规则];
-
删除
drop database[if exists]数据库名;
-
使用
use 数据库名;
DDL表操作查询
-
查询当前数据库所有表
show tables;
-
查询表结构
DESC 表名;
-
查询指定表的建表语句
show create table 表名;
-
创建表
create table 表名( 字段1 字段1类型 [comment 字段1注释], 字段2 字段2类型 [comment 字段2注释], 字段3 字段3类型 [comment 字段3注释], ...... )[comment 表注释];
DDL修改表和删除表
-
添加字段
alter table 表名 add 字段名 类型(长度)[comment 注释][约束];
-
修改数据类型
alter table 表名 modify 字段名 新数据类型(长度);
-
修改字段名和字段类型
alter table 表名 change 旧字段名 新字段名 类型(长度)[COMMENT 注释][约束];
-
删除字段
alter table 表名 drop 字段名;
-
修改表名
alter table 表名 rename to 新表名;
-
删除表
drop table [if exists] 表名;
删除指定表,并重新创建该表(可以理解为清空这张表)。
truncate table 表名;
DML语句插入、更新和删除
-
插入(insert)
insert into table_name(字段1,字段2....) values(值1,值2....);
当给全部字段添加数据时,可以省略字段名:
insert into table_name values(值1,值2....);
第一种给指定字段添加数据,如果有字段未指定,默认数据为NULL,但是如果字段值不能为空的话,则插入失败。
当批量添加数据时,可以在values后面跟多组数据:
insert into table_name(字段1,字段2....) values(值1,值2....),(值1,值2....),(值1,值2....); insert into table_name values(值1,值2....),(值1,值2....),(值1,值2....);
注意:
- 插入数据时,指定字段顺序需要与值的顺序一一对应
- 字符串和日期类型应该包含在引号中
- 插入数据的大小应该在数据规定的范围内
-
更新(update)
update 表名 set 字段名1 = 值1,字段名2 = 值2 where 条件;
需要注意的是,如果不加后面的where条件,那么这条语句是对表中某一个或几个字段所有数据进行更改,这是相当危险的操作。
-
删除(delete)
delete from table_name where 条件;
和更新一样,如果不加条件是删除表的所有数据。在不开启事务的前提下,删除之后无法回滚,是一个很危险的操作。
delete只能删除某一条或多条数据,不能删除某个字段的值,如果要删除某个字段的值,可以使用update将字段某个值置为NULL。
DQL语句(属于数据库使用最多的)
-
DQL基础语法
select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序字段列表 limit 分页参数
-
查询多个字段
select 字段1,字段2,字段3 from table_name; select * from table_name;
*为通配符,表示查询所有字段。
-
设置别名
可以给查询的字段设置别名,其中AS可以省略
select 字段1 as 别名1,字段2 as 别名2,字段3 as 别名3 from table_name;
-
去除重复记录
select后面加上distinct。
select distinct 字段列表 from 表名;
-
-
条件查询
条件查询指的是where后面的条件该怎么写,主要见下图
-
聚合函数
主要有五种聚合函数(count、max、min、avg、sum).其功能就如其名
count可以查询某个字段的数量,但是需要主要的是,不会计算字段为NULL的字段,count(*)表示整张表有多少记录.
max(字段名)求最大的记录。
-
分组查询
select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];
where与having的区别
- 执行时机不同:where是分组之前进行过滤,如果不满足则不参与分组;而having是对分组之后的数据进行过滤
- 判断条件不同:where后面不能加聚合函数,having可以。
注意:
- 执行顺序:where>聚合函数>having
- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段没有任何意义。
-
排序查询
select 字段列表 from 表名 order by 字段1 排序方式1,字段2 排序方式2;
支持多字段排序,按照字段顺序,在前面的,先按前面排序,如果前面的字段都相等,再按照后面的字段排序。其中排序方式分为==升序(asc)排序和降序(desc)==排序,默认为asc,asc可以省略。
-
分页查询
select 字段列表 from 表名 limit 起始索引,查询记录数;
注意:
- 起始索引是从0开始,起始索引=(查询页码 - 1)*每页显示数。
- 分页查询是数据库的方言,不同数据库有不同的实现,mysql数据库中是limit。
- 如果查询的是第一页的数据,起始索引可以省略,比如limit 10;
-
执行顺序
DCL用户管理和权限控制
-
用户管理
-
查询用户
use mysql; select * from user;
mysql用户信息存储与mysql数据库中的user表。
-
创建用户
create user '用户名'@'主机名' identified by '密码';
-
修改用户密码
alter user '用户名'@'主机名' identified with mysql_native_password by '新密码';
-
删除用户
drop user '用户名'@'主机名';
-
-
权限管理
-
查询权限
show grants for '用户名'@'主机名';
-
授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
-
撤销权限
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
注意:
- 多个权限之间使用逗号隔开
- 授权时,数据库名和表名都可以使用*进行通配。
-
函数介绍
-
字符串函数
注意,substring中start是从1开始的。
-
数值函数
-
日期函数
date_add(now(),INTERVAL 70 month);#当前时间往后推70个月
其中date的格式是’2022-1-1’。
-
流程函数
约束
-
外键约束
具有外键的表称为子表,外键关联的表称为父表。
-
添加外键
# 建表时添加 create table 表名( 字段名 数据类型, ...... [constraint][外键名称] foreign key(外键字段名) references 主表(主表列名) ); # 其他添加 alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名);
-
删除外键
alter table 表名 drop foreign key 外键名称;
-
删除/更新行为
-
多表查询
-
多表关系
项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的联系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在各种联系,基本上分为三种:
- 一对多(多对一):在多的一方建立外键,指向一的一方,即多的一方为子表,一的一方为父表
- 多对多:建立第三方中间表,中间表至少包含两个外键,分别指向两方
- 一对一:在任意一方设置外键,指向另一方的主见,并设置外键为唯一。
-
多表查询概述
一般在进行多表查询时,如果不加约束条件会产生这样的笛卡尔积的情况,所以后面一般都会有where条件,一般是两个字段相等。
-
内连接
-
外连接
- 自连接
- 联合查询
其中,如果union后面加上all表示不去重,不加all表示去重
- 子查询
事务
-
事务简介
事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起提交给系统,那么这些操作要么一起成功,要么一起失败。抛出异常时进行回滚,保证数据的正确性和完整性。
-
事务操作
-
开启事务
begin; set @@autocommit = 0; start transaction;
-
提交事务
commit;
-
回滚事务
当出现异常时执行
rollback;
-
-
事务的四大特性
- 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败;
- 一致性(Consistency):事务完成时,必须使所有的数据保持一致的状态
- 隔离性(Isolation):数据库提供的隔离机制,保证事务在不受外部并发操作的影响下独立运行。
- 持久性(Durability):事务一旦提交或回滚,他对数据库的影响就是永久的。
-
并发事务问题
问题 描述 脏读 一个事务读到另一个事务还没有提交的数据 不可重复度 一个事务先后读取统一数据,但读的数据不一样。 幻读 一个数据按照条件查询时,没有对应的数据行,但是在插入数据时也发现该数据存在。 -
事务隔离级别
表格中的叉表示在这种隔离级别下没有该问题。
需要设置系统变量transaction_isolation;
select @@transaction_isolation; set [session|global] transaction isolation level {Read uncommitted|Read committed|Repeatable|serializable};
进阶
存储引擎
- MySQL当前默认的存储引擎为InnoDB,这是一个同事兼顾了数据的完整性和正确性以及执行效率的引擎,此外,还需要了解另外两种引擎,MyISAM和Memory引擎
MyISAM:MyISAM作为MySQL早期的默认存储引擎,其特点在于访问速度快,相比于InnoDB,他不支持事务,不支持外键,支持表锁,但不支持行锁。其在磁盘中存储的文件有:xxx.sdi,用于存储表的结构信息;xxx.MYD,用于存储数据;xxx.MYI,用于存储索引。
Memory:Memory引擎相比于InnoDB来说,其数据库数据均存在于内存之中,最大的特点在于其执行速度很快。
InnoDB:InnoDB引擎支持行级锁,支持事务,支持外键。其文件后最名为.ldb
在选择存储引擎的时候,应该根据饮用系统的特点选择合适的存储引擎,对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合
- InnoDB:是MySQL的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,那么InnoDB引擎是比较合适的选择。
- MyISAM:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作。并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。
- MEMORY:见所有数据保存在内存中,访问速度快,通常用于临时表及缓存。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性。
索引
索引概述
索引是为了加快数据的查询速度,降低数据库的IO成本,通过索引列对数据进行排序,降低数据排序成本,降低CPU的消耗。但是索引本身需要占据存储空间,并且在加快查询速度的同时,会降低更新表的效率,因为每一次更新会影响已经建好的索引。
索引的结构
MySQL的索引是在存储引擎中实现的,也就意味着不同的存储引擎有着不同的索引结构,主要包好以下几种:
索引结构 | 描述 |
---|---|
B+Tree | 最常见的索引类型,大部分引擎都支持B+树索引 |
Hash索引 | 底层实现结构为Hash表,只能做精确查询,无法做范围查询和排序 |
R-Tree(空间索引) | 是MyISAM引擎的特殊索引,主要用于地理空间信息数据类型,使用较少 |
Full-text(全文索引) | 快速匹配文档 |
主要了解B+树索引和Hash索引。
- B+树索引通过字段构建一颗B+树,其特点在于,所有数据都在叶子结点,叶子结点从大到小排列形成一个双向链表。
- Hash索引通过Hash函数将索引字段映射到某个地址,当多个字段映射到同一个地址时,会构建一个链表。
索引分类
在存储引擎中,根据索引的存储形式,又可以分为以下两种:
- 聚集索引:将数据存储与索引放到了一起,索引结构的叶子结点保存了行数据,该索引必须有而且有一个,一般根据主键自动创建,如果没有主键,则按第一个唯一索引作为聚集索引,如果也没有合适的唯一索引,InnoDB会自动生成一个rowid,根据rowid自动创建。
- 二级索引:将数据与索引分开存储,索引的叶子结点关联的是对应的主键,该索引可存在多个。
索引语法
-
创建索引
create [unique | fulltext] index ind_name on table_name(colmu,...);
-
查看索引
show index from table_name;
-
删除索引
drop index idx_name on table_name;
SQL性能分析
-
SQL执行频次
可通过show [session|global] status来展示当前数据库INSERT、UPDATE、DELETE、SELECT的访问频次。效果如下:
-
慢查询日志
慢查询日志记录了所有执行时间超过指定参数long_query_time的SQL语句,慢查询日志默认关闭,需要在==/etc/my.cnf==文件中进行如下修改:
slow_query_log = 1 long_query_time = 2
日志文件的路径为:/var/lib/mysqld/localhost-slow.log。
-
profile详情
执行一系列的业务SQL操作,然后通过以下指令来查看指令的执行耗时。
# 查看每一条sql执行耗时的基本情况 show profiles; # 查看指定query_id的sql语句各个阶段的耗时情况 show profile for query query_id; # 查看指定query_id的SQL语句执行的cpu情况 show profile cpu for query query_id;
-
explain执行计划
使用explain或者desc命令获取MySQL如何执行SELECT语句的信息,包括在select语句中表的连接和连接顺序。
#直接在查询语句前加explain或者desc explain select ...
- id:select查询的序列号,表示查询中执行select子句或者事操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行)
- select_type:表示select的类型,常见的取值有SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(SELECT/WHERE之后包含了子查询)等
- type:表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、index、all。
- prossible_key:显示可能应用到这张表的索引,一个或多个。
- key:实际使用的索引,如果为NULL,则没有使用索引
- key_len:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好。
- rows:MySQL认为必须要执行查询的行数,在InnoDB引擎的表中,是一个估计值,可能并不总是准确的
- filtered:表示返回结果的行数占需要读取行数的百分比
索引使用
-
最左前缀法则:如果使用联合索引,要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列,如果跳过某一列,索引将部分失效(后面的字段索引失效)。
-
范围查询:联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效(尽量使用>=,<=).
-
在索引上列上进行运算操作,索引会失效
-
字符串不加引号,会存在隐式类型转换,索引将会失效
-
模糊查询如果在头部使用模糊查询,索引会失效(尾部不会)
-
or连接的条件,如果两侧有一个没有索引,则索引都不会生效
-
数据分布影响,MySQL评估,当进行全表查询时效率比使用索引还好时,索引失效。
-
SQL提示:SQL中加入提示语来指定MySQL使用那个索引:
#use index 建议mysql使用某个索引 explain select * from tb_user use index(idx_user_pro)where profession = '软件工程'; #ignore 忽略某个索引 explain select * from tb_user ignore index(idx_user_pro)where profession = '软件工程'; #force index 强制MySQL使用某个索引 explain select * from tb_user force index(idx_user_pro)where profession = '软件工程';
-
覆盖索引:尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),能够防止回表查询。
-
前缀索引:对于较大的字符串,我们可以考虑截取字符串的前缀作索引,能够降低IO浪费,提高查询时间。
-
推荐使用联合索引。
索引设计原则
- 针对数据量较大(百万级以上),且查询比较频繁的表建立索引(更新插入修改频繁建立索引反而降低效率)。
- 针对常作为查询条件where、order by、group by后面的字段建立索引。
- 尽量选择区分度高的列作为索引,区分度越高,使用索引的效率越高
- 如果是字符串类型的字段,字符串较长,可以针对字段特点建立前缀索引
- 尽量使用联合索引,减少单列索引,联合索引可以覆盖索引,节省存储空间,避免回表,提高效率
- 要控制索引的数量,索引的数量并不是越多越好,太多的索引会影响增删改的效率
- 如果索引列不能存储NULL值,在创建表的时候使用NOT NULL进行约束。当优化器知道每列是否包含NULL的时候,可以更好的确定哪个索引更有效的查询。
SQL优化
插入数据
-
insert优化 :批量插入、手动事务提交、主键顺序插入都能提高插入效率
-
大批量数据插入:load语句
# 客户端连接服务端的时候加上 --local-infile mysql --local-infile -uroot -p # 设置全局参数local_infile = 1,开启本地加载文件导入数据开关 set global local_infile = 1; # 执行load指令加载文件至数据库 load data local infile 'filepath' into table 'table_name' fields terminated by ',' lines terminated by '\n';
主键优化
-
数据组织方式
在InnoDB引擎中,表数据是根据主键顺序组织存放的,这种存储方式的表称为索引组织表,主键乱序插入会产生页分裂。
当删除一行数据时,实际上记录并没有物理删除,只是被标识为已删除并且它的空间变得允许被其他记录声明使用。当页中删除的数据达到默认的阈值时,附近的页会合并。
-
主键设计原则
- 满足业务需求的情况下,尽量降低主键的长度。
- 插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。
- 尽量不要使用UUID做主键或者是其他自然主键,如身份证号。
- 业务操作时,避免对主键的修改。
order by优化
- Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫filesort排序
- Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。
group by优化
建立联合索引
limit优化
select * from table limit 0,10;
大数据量下分页越往后效率越低
覆盖索引+子查询进行优化
count优化
优化思路:自己计数。
count(*),count(主键),count(字段),count(1);
update优化
InnoDB存在行锁机制,只要数据没有提交,行锁不会解。如果where后面的条件字段没有索引,那么就加的是表锁。
InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁。
所以优化思路为,根据索引字段进行更新。
视图/存储过程/触发器
视图
-
视图是一种虚拟存在的表,不存储具体的数据,而只存储数据的逻辑结构,行和列数据定义来自于定义视图查询中使用的表,并且实在使用视图时动态生成。
-
通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果,所以我们在创建视图时,主要工作就落在创建这条SQL查询语句上
-
创建视图
create or replace view 视图名称(列名列表) as select with cascaded | local check option;
-
查询
查看创建视图语句:show create view 视图名称; 查看视图数据:select * from 视图名称;
-
修改
# 方式一 create or replace view 视图名称(列名列表) as select 语句 with cascaded | local check option; # 方式二 alter view 视图名称 as select 语句 with cascaded | local check option;
-
删除
drop view [if exists] 视图名称;
-
视图的检查选项
当在进行视图数据的增删改时,真实的数据是对创建视图时select后面的表进行增删改,这样会导致数据插入到原来的真实表,但是视图中不一定有的情况发生,为了保证数据的正确性和一致性,视图加上检查选项,可以对数据插入等操作进行约束。
MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项:
- cascaded(默认)
- local
cascaded表示级联,v2基于v1创建,v2加了cascaded,v1元本没加,但也相当于家了,在进行v2的插入删除更新操作时,都会检查v1和v2创建时的条件。
local也会递归检查基于视图的创建条件,但是如果依赖的视图创建时没有加with check option,则不做检查,家了才检查。cascaded无论加不加都要检查。
-
视图的更新
要使视图可更新,视图中的行与基础表中的行必须存在一对一的关系。如果视图包含以下任何一项,则该视图不可更新:
- 聚合函数或窗口函数
- distinct
- group by
- having
- union 或 union all
-
作用
- 简单:视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
- 安全:数据库可以授权,但不能授权到数据库特定行和特定列上。通过视图用户只能查询和修改他们所能见到的数据
- 数据独立:视图可以帮助用户屏蔽真实表结构变化带来的影响。
存储过程
-
介绍
存储过程时事先经过变异并存储在数据库中的一段sql语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用。(可以理解为C++的函数)
-
特点
封装,复用
可以接受参数,也可以返回数据
减少网络交互,效率提升
-
创建
create procedure 存储过程名称([参数列表]) begin --SQL语句 end;
-
调用
call 名称([参数]);
-
查看
select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_SCHEMA='xxx';# 查询指定数据库的存储过程及状态信息 show create procedure 存储过程名称; # 查询某个存储过程的定义
-
删除
DROP procedure [if exists] 存储过程名称;
在写存储过程中有一个小细节,在编写完一条sql语句时我们需要打分号换行写下一条,但分号时数据库默认的SQL语句结束符。此时需要使用delimiter指定在命令行中以什么字符结束语句。
-
变量
系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION)。
-
查看系统变量
SHOW [SESSION|GLOBAL] VARIABLES; # 查看所有系统变量 show [SESSION|GLOBAL] VARIABLES like '....'; # 模糊匹配 select @@[SESSION|GLOBAL]系统变量名;# 查看指定变量的值
-
设置系统变量
set [SESSION|GLOBAL] 系统变量名 = 值; set @@[SESSION|GLOBAL]系统变量名 = 值;
注意:
如果没有指定SESSION/GLOBAL,默认是session,会话变量
mysql服务重新启动之后,所设置的全局参数会失效,要想不失效,可在/etc/my.cnf中配置。
用户定义变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@变量名”使用就可以。其作用域为当前连接
-
赋值
set @var_name = expr; set @var_name := expr; select @var_name := expr; select 字段名 into @var_name from 表名;
-
使用
select @var_name;
局部变量是根据需要定义的在局部生效的变量,访问之前需要declare声明。可用作存储过程内的局部变量和输入参数,局部变量的范围是其内声明的begin…end块。
-
声明
declare 变量名 变量类型 [default ...];
变量类型就是数据库字段类型:int,bigint,char,varchar,date,time等。
-
赋值
set 变量名 = 值; set 变量名 := 值; select 字段名 into 变量名 from 表名;
-
-
if
语法
if 条件1 then elseif 条件2 then else end if;
-
参数
类型 含义 备注 IN 输入参数 默认 out 输出 inout 既可以输入也可输出 用法:
create procedure 存储过程名称([IN/out/INOUT 参数名称 参数类型]) begin -- SQL语句 end;
-
case
-
语法一
CASE case_value WHEN when_value1 then statement_list1 [WHEN when_value2 then statement_list2]... [ELSE statement_list] end case;
-
语法二
CASE case_value WHEN search_condition1 then statement_list1 [WHEN search_condition2 then statement_list2]... [ELSE statement_list] end case;
-
-
while
while循环是有条件的循环控制语句。满足条件后,再执行循环体中的SQL语句。具体语法为:
WHILE 条件 DO SQL逻辑 end while;
-
repeat
repeat是有条件的循环控制语句,当满足条件时退出循环。具体语法为:
repeat SQL逻辑 until 条件 end repeat;
-
loop
loop实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用其来实现简单的死循环,loop可以配合以下两个语句使用
- leave:退出循环,相当于C++中的break;
- iterate:相当于C++中的continue;
[begin_label:] loop sql逻辑 end loop[end_label];
Leave label; 退出指定标记的循环体
Iterate label;直接进入下一次循环
-
游标
游标(cursor)是用来存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、open、fetch和close,其语法分别如下。
-
声明游标
declare 游标名称 cursor for 查询语句;
-
打开游标
open 游标名称;
-
获取游标记录
FETCH 游标名称 into 变量 [,变量];
-
关闭游标
close 游标名称;
-