MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(4)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】

MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(3)https://developer.aliyun.com/article/1534304

3.3.10、循环语句和循环控制

先介绍循环控制:

  • leave:类似于 break
  • iterate:类似于 continue
1. while 循环

语法

[标签]: while 循环条件 do
    循环体
end while [标签];

测试:

delimiter $$
create procedure func11()
begin
    declare i int default 0;
    declare num int default (select count(*) from emp);
    while i<num do
        select i;
        set i = i+1;
    end while;
end $$
delimiter ;
 
call func11();

测试结果就是会创建 num 张表,表内就是 i 的值。

2. repeat 循环

语法

[标签:] repeat
    循环体;
until 条件表达式
end repeat 标签;

测试:

delimiter $$
create procedure func12()
begin
    declare i int default 0;
    label: repeat
        set i = i+1;
        until i > 10
    end repeat label;
    select '循环结束';
end $$
delimiter ;
 
call func12();
3. loop 循环

语法

[标签:] loop
    循环体
    if 条件表达式 then
        leave 标签;
    endif;
end loop;

测试:

delimiter $$
create procedure func13()
begin
    declare i int default 0;
    label: loop
        if i!=5 then
            set i = i+1;
        else leave label;
        end if;
    end loop;
end $$
delimiter ;
 
call func13();

3.3.11、存储过程之游标(Cursor)

       游标(cursor)是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用光标对结果集进行循环的处理。光标的使用包括光标的声明、OPEN、FETCH 和 CLOSE.

语法

-- 声明语法
declare cursor_name cursor for select_statement
-- 打开语法
open cursor_name
-- 取值语法
fetch cursor_name into var_name [, var_name] ...
-- 关闭语法
close cursor_name

测试:

-- 游标
delimiter $$
create procedure func14(in id int)
begin
    -- 声明局部变量
    declare eid int;
    declare ename char(20);
    declare esalary decimal(10,2);
 
    -- 声明游标
    declare my_cursor cursor for
        select emp_id,emp_name,salary
            from emp
            where emp_id=id;
 
    -- 打开游标
    open my_cursor;
 
    -- 通过游标获取每一行
    label: loop
        fetch my_cursor into eid,ename,esalary;
        select eid,ename,esalary;
        leave label;
    end loop;
 
    -- 关闭游标
    close my_cursor;
end $$
delimiter ;
 
drop procedure func14;
 
 
call func14(1);

注意循环体中必须有退出的条件,否则就是死循环!

3.3.12、句柄 handler

4、存储函数(自定义函数)

注意:自定义函数之前必须设置全局变量:

-- 信任函数的创建者
set global log_bin_trust_function_creators=TRUE;
-- 信任函数的创建者
set global log_bin_trust_function_creators=TRUE;
 
delimiter $$
create function oneToNum(n int) returns int
begin
    declare sum int default 0;
    while n!=0 do
        set sum = sum + n;
        set n = n-1;
    end while;
    return sum;
end $$
delimiter ;
 
select oneToNum(3); --6

注意:自定义函数不能包含递归,递归需要使用专门的语法。

5、触发器

5.1、介绍

  • 触发器,就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段,但是触发器无需调用,当对数据库表中的数据执行DML操作时自动触发这个SQL片段的执行,无需手动条用。
  • 在MySQL中,只有执行insert,delete,update操作时才能触发触发器的执行
  • 触发器的这种特性可以协助应用在数据库端确保数据的完整性 , 日志记录 , 数据校验等操作 。
  • 使用别名 OLD 和 NEW 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。

5.2、触发器的特性

  • 什么条件会触发:I、D、U
  • 什么时候触发:在增删改前或者后
  • 触发频率:针对每一行执行
  • 触发器定义在表上,附着在表上

5.3、触发器语法

5.3.1、创建只有一个执行语句方触发器

注意:这里的触发事件只能是 insert、update、delete。

create trigger 触发器名 before|after 触发事件
on 表名 for each row 
执行语句;

5.3.2、创建有多个执行语句的触发器

create trigger 触发器名 before|after  触发事件 
on 表名 for each row
begin
     执行语句列表
end;

5.4、触发器的使用

5.4.1.创建触发器

-- 触发器
drop trigger if exists trigger_emp;
 
-- 创建受触发器影响的表格
create table emp_log(
    id int primary key auto_increment,
    time timestamp,
    log_text varchar(255)
);
 
-- 创建触发器
create trigger trigger_emp
after insert on emp
for each row
insert into emp_log values (NULL,now(),'新的员工注册');
 
insert into emp values (NULL,'刘海柱',8999,'技术部');

当向 emp 表进行 insert 操作时,就会触发触发器向 emp_log 插入一条日志。

5.4.2、NEW 和 OLD

MySQL 中定义了 NEW 和 OLD,用来表示触发器的所在表中,触发了触发器的那一行数据,来引用触发器中发生变化的记录内容,具体地:

       这让我很自然的联想到了 MySQL 的 binlog 功能,我们数仓中使用 MaxWell 来监听 binlog 实现数据同步,但是 binlog 的底层并不是触发器。

语法

NEW.列名
OLD.列名

测试:

-- 不要影响到其它触发器对 emp_log 的操作,比如这里增加了两个字段,
-- 当对该表进行insert 操作时,因为给 emp_log 增加字段之后没有更新触发器的行为
-- 就会导致给 emp 和 emp_log 插入数据是全部失败
 
alter table emp_log add old varchar(50);
alter table emp_log add new varchar(50);
 
create trigger trigger_test
after update
on emp for each row
insert into emp_log values (
                            null,now(),
                            concat('更新数据'),
                            concat(OLD.emp_id,OLD.emp_name,OLD.salary,OLD.department),
                            concat(NEW.emp_id,NEW.emp_name,NEW.salary,NEW.department)
);
update emp set emp_name = '李元芳' where emp_id = 3;
 
select * from emp_log;

5.5、触发器使用的注意事项

  • MYSQL中触发器中不能对本表进行 insert ,update ,delete 操作,以免递归循环触发
  • 尽量少使用触发器,假设触发器触发每次执行1s,insert table 500条数据,那么就需要触发500次触发器,光是触发器执行的时间就花费了500s,而insert 500条数据一共是1s,那么这个insert的效率就非常低了。
  • 触发器是针对每一行的;对增删改非常频繁的表上切记不要使用触发器,因为它会非常消耗资源。

MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(5)

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
4月前
|
关系型数据库 MySQL 数据库
Mysql的索引
MYSQL索引主要有 : 单列索引 , 组合索引和空间索引 , 用的比较多的就是单列索引和组合索引 , 空间索引我这边没有用到过 单列索引 : 在MYSQL数据库表的某一列上面创建的索引叫单列索引 , 单列索引又分为 ● 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。 ● 唯一索引:索引列中的值必须是唯一的,但是允许为空值 ● 主键索引:是一种特殊的唯一索引,不允许有空值 ● 全文索引: 只有在MyISAM引擎、InnoDB(5.6以后)上才能使⽤用,而且只能在CHAR,VARCHAR,TEXT类型字段上使⽤用全⽂文索引。
|
2月前
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
76 12
|
3月前
|
SQL 存储 关系型数据库
MySQL选错索引了怎么办?
本文探讨了MySQL中因索引选择不当导致查询性能下降的问题。通过创建包含10万行数据的表并插入数据,分析了一条简单SQL语句在不同场景下的执行情况。实验表明,当数据频繁更新时,MySQL可能因统计信息不准确而选错索引,导致全表扫描。文章深入解析了优化器判断扫描行数的机制,指出基数统计误差是主要原因,并提供了通过`analyze table`重新统计索引信息的解决方法。
|
4月前
|
自然语言处理 关系型数据库 MySQL
MySQL索引有哪些类型?
● 普通索引:最基本的索引,没有任何限制。 ● 唯一索引:索引列的值必须唯一,但可以有空值。可以创建组合索引,则列值的组合必须唯一。 ● 主键索引:是特殊的唯一索引,不可以有空值,且表中只存在一个该值。 ● 组合索引:多列值组成一个索引,用于组合搜索,效率高于索引合并。 ● 全文索引:对文本的内容进行分词,进行搜索。
|
22天前
|
人工智能 运维 关系型数据库
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
161 1
|
2月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
4月前
|
关系型数据库 MySQL Java
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
|
2月前
|
存储 关系型数据库 MySQL
大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
本文详细介绍了在 MySQL 中创建数据库和表的方法。包括安装 MySQL、用命令行和图形化工具创建数据库、选择数据库、创建表(含数据类型介绍与选择建议、案例分析、最佳实践与注意事项)以及查看数据库和表的内容。文章专业、严谨且具可操作性,对数据管理有实际帮助。
大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
|
2月前
|
SQL 关系型数据库 MySQL
MySQL下载安装全攻略!小白也能轻松上手,从此数据库不再难搞!
这是一份详细的MySQL安装与配置教程,适合初学者快速上手。内容涵盖从下载到安装的每一步操作,包括选择版本、设置路径、配置端口及密码等。同时提供基础操作指南,如数据库管理、数据表增删改查、用户权限设置等。还介绍了备份恢复、图形化工具使用和性能优化技巧,帮助用户全面掌握MySQL的使用方法。附带常见问题解决方法,保姆级教学让你无忧入门!
MySQL下载安装全攻略!小白也能轻松上手,从此数据库不再难搞!

热门文章

最新文章

推荐镜像

更多