目录

  • 存储过程procedure
    • 创建 -- delimiter -- call
    • 删除 -- drop
    • 添加参数
      • 默认值参数
      • 参数验证 -- decimal、 singal sqlstate
    • 输出参数 -- 少用
    • 变量
      • 用户或会话 变量 @ -- 用户断线时,变量清空
      • 本地变量 declare decimal --- 执行计算任务
    • 函数 -- 单一值
  • 触发器 -- 保证数据一致性
    • 创建
    • 查看 -- 命名习惯
    • 使用触发器进行审计
  • 事件 -- MySQL事件调度器 -- 自动启动
    • 创建
    • 删除drop,更改 alter
  • 事务 -- 多个操作保持一致
    • 创建
  • 并发和锁定 --- 难点
    • 常见并发问题
      • 丢失更新
      • 脏读
      • 不可重复读
      • 幻读 -- 突然出现数据
    • 事务隔离级别-- 默认为 repeatable read
      • 设置
    • 死锁 Deadlock 错误码:1213
  • 传送门

存储过程procedure

创建 – delimiter – call

delimiter $$
create procedure get_clients() -- () 用于添加参数为存储过程传递值
beginselect * from clients;
end $$
delimiter ;
call get_clients  -- 使用 call 调用存储过程
也可用 'c#',Java,python 等应用代码调用存储过程
delimiter $$
create procedure get_invoices_with_balance()
begin select *from invoiceswhere (invoice_total - payment_total) > 0;
end $$
delimiter ;

删除 – drop

drop procedure if exists get_clients -- if exists 防止重复删除delimiter $$
create procedure get_clients ()
beginselect *from clientswhere (invoice_total - payment_total)>0;
end $$
delimiter ;

添加参数

drop procedure if exists get_clients_by_state;delimiter $$
create procedure get_clients_by_state(state char(2))
beginselect *from clients cwhere c.state =state;
end $$
delimiter ;-- call get_clients_by_state('CA')

drop procedure if exists get_invoices_by_client;
delimiter $$
create procedure get_invoices_by_client(client_id int) -- 类型看设计表
begin select *from invoices iwhere i.client_id = client_id;
end $$
delimiter ;

默认值参数

drop procedure if exists get_clients_by_clients;delimiter $$
create procedure get_clients_by_clients(state char(2))
beginif state is null then set state = 'CA'; end if;select *from clients cwhere c.state = state ;end
$$
delimiter ;call get_clients_by_clients(null)
drop procedure if exists get_clients_by_clients;delimiter $$
create procedure get_clients_by_clients(state char(2))
beginif state is null then -- 未传参 显示全部select *from clients ;elseselect *from clients cwhere c.state = state ;end if;
end
$$
delimiter ;call get_clients_by_clients(null)
drop procedure if exists get_clients_by_clients;delimiter $$
create procedure get_clients_by_clients(state char(2))
beginselect *from clients c-- 若state 为空则 c.state = c.state 永久满足where c.state = ifnull(state,c.state) ; end
$$
delimiter ;call get_clients_by_clients('CA')
drop procedure if exists get_payments;
delimiter $$
create procedure get_payments(client_id int,payment_method_id tinyint)
begin select *from payments pwhere p.client_id = ifnull(client_id,p.client_id) and p.payment_method = ifnull(payment_method_id,p.payment_method);
end
$$
delimiter ;call get_payments(null,2)

参数验证 – decimal、 singal sqlstate

drop procedure if exists make_payment;
delimiter $$
create procedure make_payment(invoice_id int,-- decimal 小数类型 9位数,其中2位小数payment_amount decimal(9,2),payment_date date
)
beginif payment_amount < = 0 thensignal sqlstate '22003' -- signal 抛出异常-- 给开发设置错误信息set message_text = 'invalid payment amount';end if;update invoices iseti.payment_total = payment_amount,i.payment_date = payment_datewhere i.invoice_id = invoice_id;
end
$$
delimiter ;call make_payment(2,-100,'2019-01-01');

输出参数 – 少用

drop procedure if exists get_uppaid_invoices_for_client;
delimiter $$
create procedure get_uppaid_invoices_for_client(client_id int,-- out 修正为输出参数out invoices_count int, out invoices_tatal decimal(9,2)
)
beginselect count(*),sum(invoice_total)into invoices_count,invoices_tatalfrom invoices iwhere i.client_id = client_id and payment_total = 0;
end
$$
delimiter ;

变量

用户或会话 变量 @ – 用户断线时,变量清空

通常我们会在调用输出参数的存储过程时使用这些变量
set @invoices_count = 0

本地变量 declare decimal — 执行计算任务

drop procedure if exists get_risk_factor;
delimiter $$
create procedure get_risk_factor()
begin-- declare 声明本地变量declare risk_factor decimal(9,2) default 0;declare invoices_total decimal(9,2);declare invoices_count int;select count(*),sum(invoice_total)into invoices_count,invoices_totalfrom invoices;set risk_factor = invoices_total / invoices_count * 5;select invoices_total,invoices_count,risk_factor;
end
$$
delimiter ;
call get_risk_factor();

函数 – 单一值

drop function if exists get_risk_factor_for_client;
delimiter $$
-- 函数 还能返回 单一值
create function get_risk_factor_for_client(client_id int)
returns integer  -- 确定返回值类型为 integer
-- 设置函数属性
-- deterministic -- 确定性
reads sql data -- 存在选择语句 读取数据
-- modifies sql data -- 修改数据
begin declare risk_factor decimal(9,2) default 0;declare invoices_total decimal(9,2);declare invoices_count int;select count(*),sum(invoice_total)into invoices_count,invoices_totalfrom invoices iwhere i.client_id = client_id;set risk_factor = invoices_total / invoices_count * 5;-- 0 / null = nullreturn ifnull(risk_factor,0);
end$$
delimiter ;
select client_id,`name`,-- 0 / null = nullget_risk_factor_for_client(client_id) as risk
from clients

触发器 – 保证数据一致性

创建

drop trigger if exists payments_after_insert;
delimiter $$create trigger payments_after_insert   -- 触发器在 payments 插入后 触发-- before delete/update on paymentsafter insert on paymentsfor each row -- 触发器会作用于每个受影响的行
beginupdate invoices-- new 返回刚插入的行 ;old 返回刚删除或更新的行set payment_total = payment_total + new.amount,payment_date = new.datewhere invoice_id = new.invoice_id;
end$$
delimiter ;
insert into payments
values(default,5,2,'2019-10-10',10,1)
drop trigger if exists payments_after_delete;
delimiter $$
create trigger payments_after_deleteafter delete on paymentsfor each row
beginupdate invoicesset payment_total = payment_total - old.amountwhere invoice_id = old.invoice_id;
end
$$
delimiter ;
delete from payments
where payment_id = 9

查看 – 命名习惯

show triggers like 'payments%'

使用触发器进行审计

-- 创建一个审计表
drop table if exists payments_audit;
create table payments_audit
(client_id int not null,date date not null,amount decimal(9,2),action_type varchar(50) not null,action_date datetime not null
)
drop trigger if exists payments_after_insert;
delimiter $$create trigger payments_after_insert   -- 触发器在 payments 插入后 触发-- before delete/update on paymentsafter insert on paymentsfor each row -- 触发器会作用于每个受影响的行
beginupdate invoices-- new 返回刚插入的行 ;old 返回刚删除或更新的行set payment_total = payment_total + new.amount,payment_date = new.datewhere invoice_id = new.invoice_id;-- 往审计表里添加记录insert into payments_auditvalues (new.client_id,new.date,new.amount,'insert',now());
end$$
delimiter ;
insert into payments
values(default,5,2,'2019-10-10',10,1)

事件 – MySQL事件调度器 – 自动启动

创建

-- 查看事件调度器
show variables like 'event%';
-- 设置调度器为开 / 关 on / off
set global event_scheduler = on ;

删除drop,更改 alter

drop event if exists yearly_delete_stale_audit_rows;
delimiter $$
-- alter event ...
create event yearly_delete_stale_audit_rows
on schedule
--  at '2022-03-03' -- 单次定时操作-- every 循环工作every 1 day starts '2019-01-01' ends '2029-02-01'
do begindelete from payments_audit;-- where action_date < NOW() - interval 1 year;
end
$$
delimiter ;
-- 查看事件
show events like 'year%'
-- 修改
alter event yearly_delete_stale_audit_rows disable ; -- enable

事务 – 多个操作保持一致

创建

start transaction; -- 创建事务
insert into orders(customer_id,order_date,status)
values(1,'2019-01-01',1);insert into order_items
values(last_insert_id(),1,1,1)commit; -- 提交事务事务 -- 把所有更改写入到数据库
-- rollback -- 回滚 -- 设置条件 取消处理

查看 自动提交引擎 autocommit 状态, 默认开启 on

show variables like 'autocommit'

并发和锁定 — 难点

常见并发问题

丢失更新

脏读

不可重复读

幻读 – 突然出现数据

事务隔离级别-- 默认为 repeatable read

设置

         SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL isolation-level其中的<isolation-level>可以是:–    READ UNCOMMITTED–   READ COMMITTED– REPEATABLE READ–    SERIALIZABLE

first connection
-- 只会对下一个事务起作用
set transaction isolation level read uncommitted;  -- 存在脏读问题
-- mysql 执行的每一个语句 都会在事务中打包 并自动提交
select points from customers where customer_id = 1;
set transaction isolation level read committed; -- 克服脏读 但存在同一事件两次读 数据不一致
-- mysql 执行的每一个语句 都会在事务中打包 并自动提交
select points from customers where customer_id = 1;
set transaction isolation level repeatable read; -- 克服数据读取不一致,但存在幻读
start transaction;
select * from customers where state = 'VA';
commit;
set transaction isolation level serializable; -- 克服幻读
start transaction;
select * from customers where state = 'VA';
commit;
 在逐行运行到select时去运行第二连接的事务但不要提交,由于是序列级别,所以第一连接事务的select 会等待第二连接事务的提交 commit

second connection
start transaction ;
update customers set points = 20 where customer_id = 1;
-- commit ;
rollback ;
start transaction ;
update customers set state = 'VA' where customer_id = 1;
commit ;

死锁 Deadlock 错误码:1213

如果事务以相反的顺序更新记录,很可能会发生死锁
 -- first connection
start transaction ;
update orders set status = 2 where order_id = 1;
update customers  set state = 'cc' where customer_id = 1;
commit;
-- second connection
start transaction ;
update customers  set state = 'cc' where customer_id = 1;
update orders set status = 2 where order_id = 1;
commit;

传送门

SQL进阶教程 | 史上最易懂SQL教程!10小时零基础成长SQL大师!!
SQL存储过程有什么用?
MySql中delimiter的作用是什么?
Navicat Premium 查询sql文件保存位置在哪里?
SQLSTATE values and common error codes
从SQL语言的分类谈COMMIT和ROLLBACK的用法
关于mysql的参数autocommit
SQL-数据库脏读、不可重复读、幻象读的解释
sql server 并发_并发问题– SQL Server中的理论和实验
MySQL查看和修改事务隔离级别
3分钟搞懂MySQL事务隔离级别及SET TRANSACTION影响事务

CodeWithMosh--mysql 学习笔记(3)相关推荐

  1. 【mysql学习笔记整理】

    /*mysql学习笔记整理*/ /*常用的数据库操作对象*/ #库的操作 #创建 #数据库的创建 USE mysql; CREATE DATABASE db_x; #删除 #删除数据库 DROP DA ...

  2. 初识mysql学习笔记

    使用VMVirtualBox导入Ubuntu后,可以通过sudo apt-get install mysql-server命令下载mysql. 在学习过程中,我遇到了连接不上Xshell的问题.最终在 ...

  3. MySQL学习笔记07【事务、用户管理和权限管理】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  4. MySQL学习笔记06【多表查询、子查询、多表查询练习】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  5. MySQL学习笔记05【多表操作、三大范式、数据库的备份和还原】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  6. MySQL学习笔记04【数据库的查询操作、今日内容、表的约束】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  7. MySQL学习笔记03【数据库表的CRUD操作、数据库表中记录的基本操作、客户端图形化界面工具SQLyog】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  8. MySQL学习笔记02【SQL基本概念与通用语法、数据库的CRUD操作】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  9. MySQL学习笔记01【数据库概念、MySQL安装与使用】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  10. Mysql学习笔记(七)查(补充)

    Mysql学习笔记(七)查(补充) 原文:Mysql学习笔记(七)查(补充) PS:五一还是要学习...虽然有点苦逼..但是路是自己选的,那么自己就要坚持的走下去... 学习内容: 1.数据库查找的补 ...

最新文章

  1. 团队项目第二阶段冲刺站立会议01
  2. spark 持久化 mysql_Spark 从零到开发(八)nginx日志清洗并持久化实战
  3. vs服务器连接xp系统,xp系统远程连接服务器
  4. Git分支 and PullFetchMerge
  5. 蓝桥杯 ALGO-93 算法训练 反置数
  6. 游戏服务器运维需要注意,网络游戏服务器维护时都是在做些什么?
  7. SQL语句中查询数据
  8. UE使用EditorUtilityWidget完成简单的编辑器内工具
  9. 安装Aras Innovator
  10. ToC产品和ToB产品的区别
  11. 怎么制定市场营销策划方案
  12. python Flask 10 Flask请求上下文管理werkzeug
  13. 超图软件的下载及授权配置
  14. java心得!--很好的java学习历程(转自张国宝)
  15. matlab四元一次非线性方程求解,[转载]MATLAB求解非线性方程(转)
  16. ESP8266_04-------------串口的使用
  17. 降水数据下载地址汇总
  18. java读取potx
  19. 我协会负责人调研东风汽车·····
  20. 青年男女的爱情宝典(未婚必看)

热门文章

  1. C++ Primer Plus 读书笔记(第4、5章)
  2. linux下tar压缩使用
  3. Physics-based Animation 相关
  4. Git详解(1)——Git起步
  5. NLP情感分析笔记(一):Baseline
  6. 大数据可视化如何实现
  7. 大数据分析常见的9个错误
  8. 视频监控物联卡有什么作用
  9. .xyz文件_Orca.xyz:除了银行系统瑞士还有同样安全的数字保险箱
  10. access month函数用法_掌握时间智能函数,同比环比各种比,轻松搞定!