mysql:视图,触发器,事务,存储过程,函数
一、视图
视图是一个虚拟表并不是(正实存在的)
创建老师表 create table teacher(
id int primary key auto_increment,
tname varchar()
); 创建课程表
create table course(
id int primary key auto_increment,
cname varchar(),
teacher_id int,
foreign key(teacher_id) references teacher(id)
on delete cascade
on update cascade
); 插入数据
insert into teacher(tname)values
('张磊老师'),
('李平老师'),
('刘海燕老师'),
('朱云海老师'),
('李杰老师'); insert into course(cname,teacher_id)values
('生物',),
('物理',),
('体育',),
('美术',);
两张有关系的表
#查询李平老师教授的课程名
#子查询出临时表,作为teacher_id等判断依据
select tid from teacher where tname='李平老师'
(1)创建视图
#语法:CREATE VIEW 视图名称 AS SQL语句
#于是查询李平老师教授的课程名的sql可以改写为![]()
#!!!注意注意注意:
#1. 使用视图以后就无需每次都重写子查询的sql,但是这么效率并不高,还不如我们写子查询的效率高
#2. 而且有一个致命的问题:视图是存放到数据库里的,如果我们程序中的sql过分依赖于数据库中存放的视图,
那么意味着,一旦sql需要修改且涉及到视图的部分,则必须去数据库中进行修改,而通常在公司中数据库有专门的DBA负责,
你要想完成修改,必须付出大量的沟通成本DBA可能才会帮你完成修改,极其地不方便
(2)、使用视图
#修改视图,原始表也跟着改![]()
![]()
(3)修改视图
语法:ALTER VIEW 视图名称 AS SQL语句
(4)删除视图
语法:DROP VIEW 视图名称
DROP VIEW teacher_view
二、触发器
使用触发器可以定制用户对表进行【增、删、改】操作时前后的行为,注意:没有查询
(1)创建触发器
# 插入前
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
...
END # 插入后
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN
...
END # 删除前
CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN
...
END # 删除后
CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
BEGIN
...
END # 更新前
CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END # 更新后
CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END
#准备表
CREATE TABLE cmd (
id INT PRIMARY KEY auto_increment,
USER CHAR (),
priv CHAR (),
cmd CHAR (),
sub_time datetime, #提交时间
success enum ('yes', 'no') #0代表执行失败
); CREATE TABLE errlog (
id INT PRIMARY KEY auto_increment,
err_cmd CHAR (),
err_time datetime
); #创建触发器
delimiter //
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
BEGIN
IF NEW.success = 'no' THEN #等值判断只有一个等号
INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号
END IF ; #必须加分号
END//
delimiter ; #往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (
USER,
priv,
cmd,
sub_time,
success
)
VALUES
('egon','','ls -l /etc',NOW(),'yes'),
('egon','','cat /etc/passwd',NOW(),'no'),
('egon','','useradd xxx',NOW(),'no'),
('egon','','ps aux',NOW(),'yes');
#查询错误日志,发现有两条
特别的:NEW表示即将插入的数据行,OLD表示即将删除的数据行。
(2)、 使用触发器
触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的。
(3)、 删除触发器
drop trigger tri_after_insert_cmd;
三、事务
事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,
即可回滚到原来的状态,从而保证数据库数据完整性。
create table user(
id int primary key auto_increment,
name char(),
balance int
); insert into user(name,balance)
values
('wsb',),
('egon',),
('ysb',); #原子操作
start transaction;
update user set balance= where name='wsb'; #买支付100元
update user set balance= where name='egon'; #中介拿走10元
update user set balance= where name='ysb'; #卖家拿到90元
commit; #出现异常,回滚到初始状态
start transaction;
update user set balance= where name='wsb'; #买支付100元
update user set balance= where name='egon'; #中介拿走10元
uppdate user set balance= where name='ysb'; #卖家拿到90元,出现异常没有拿到
rollback;
commit;
四、存储过程
存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,
通过调用它的名字可以执行其内部的一堆sql
使用存储过程的优点
#1 程序与数据实现解耦
#2 减少网络传输的数据量
#===============================================
#创建无参存储过程
delimiter //
create procedure p3()
begin
select * from user;
insert into user(name,balance) values('wsb1',);
end //
delimiter ; #调用存储过程
call p3(); #在mysql中调用
cursor.callproc('p3') #在python中通过pymysql模块调用 #===============================================
#创建有参存储过程之in的使用
delimiter //
create procedure p4(
in m int,
in n int
)
begin
select * from user where id between m and n;
end //
delimiter ; #调用存储过程
call p4(,); #在mysql中调用
cursor.callproc('p4',args=(,)) #在python中通过pymysql模块调用 #===============================================
#创建有参存储过程之out的使用
delimiter //
create procedure p5(
in m int,
in n int,
out res int
)
begin
select * from user where id between m and n;
set res=;
end //
delimiter ; #调用存储过程
#在mysql中
set @x=
call p5(,,@x); #在mysql中调用, 查看结果:select @x;
#在python中
res=cursor.callproc('p5',args=(,,)) #@_p3_0=,@_p3_1=,@_p3_2=
print(cursor.fetchall()) #只是拿到存储过程中select的查询结果
cursor.execute('select @_p5_0,@_p5_1,@_p5_2')
print(cursor.fetchall()) #可以拿到的是返回值 #===============================================
#创建有参存储过程之inout的使用 delimiter //
create procedure p6(
inout m int
)
begin
select * from user where id > m;
set m=;
end //
delimiter ; #在mysql中
set @x=;
call p6(@x);
select @x;
delimiter //
create procedure p8(
inout m int
)
begin
select * from user111 where id > m;
set m=;
end //
delimiter ; set @x=;
call p8(@x);
select @x; #====================捕捉异常+事务===========================
delimiter //
create PROCEDURE p9(
OUT p_return_code tinyint
)
BEGIN
DECLARE exit handler for sqlexception
BEGIN
-- ERROR
set p_return_code = ;
rollback;
END; DECLARE exit handler for sqlwarning
BEGIN
-- WARNING
set p_return_code = ;
rollback;
END; START TRANSACTION;
insert into user(name,balance) values('egon',);
DELETE from tb1111111; #执行失败
COMMIT; -- SUCCESS
set p_return_code = ; #0代表执行成功 END //
delimiter ; #用python模拟
try:
START TRANSACTION;
DELETE from tb3; #执行失败
insert into blog(name,sub_time) values('yyy',now());
COMMIT;
set p_return_code = ; #0代表执行成功
except sqlexception:
set p_return_code = ;
rollback;
except sqlwaring:
set p_return_code = ;
rollback; mysql> show procedure status like 'p3%'; #查看某一类存储过程
五、流程控制
#函数中不要写sql语句,它仅仅只是一个功能,是一个在sql中被应用的功能
#若要想在begin...end...中写sql,请用存储过程
#while循环
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN DECLARE num INT ;
SET num = ;
WHILE num < DO
SELECT
num ;
SET num = num + ;
END WHILE ; END //
delimiter ;
mysql:视图,触发器,事务,存储过程,函数的更多相关文章
- MySQL 视图触发器事务存储过程函数
事务 致命三问 什么是事务:开启了一个包含多条SQL语句的事务,这些SQL语句要么都执行成功,要么有别想成功:例如A向B转账,二人账户并不属于一家银行,在转账过程中由于网络问题,导致A显示转账 成功 ...
- MySQL 视图 触发器 事务 存储过程 函数 流程控制 索引与慢查询优化
视图 1.什么是视图? 视图就是通过查询得到的一张虚拟表,然后保存下来,下次可直接使用 2.为什么要使用视图? 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图? create view ...
- MySQL——视图/触发器/事务/存储过程/函数/流程控制
一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- MySQL视图,触发器,事务,存储过程,函数
create triggr triafterinsertcmdlog after insert on cmd_log FOR EACH ROW trigger_body .#NEW : 代表新的记录 ...
- mysql 视图 触发器 事物 存储过程 函数 流程控制
1.视图 *** 视图是有一条sql语句的查询结果构成的虚拟表 其不是物理存在的 使用方式与普通表相同 视图的作用1.简化sql语句的编写 2.限制可以查看的数据 可以使用权限来完成 权限某一个库 的 ...
- MySQL_视图/触发器/事务/存储过程/函数
视图.触发器.事务.存储过程.函数 视图 视图是一个虚拟表(非真实存在),其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集,可以将该结果集当作表来使用 #创建视 ...
- MySQL拓展 视图,触发器,事务,存储过程,内置函数,流程控制,索引,慢查询优化,数据库三大设计范式
视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 create view tea ...
- python mysql 视图 触发器 事物 存储过程 用户授权 数据备份还原
###################总结########### 视图是一个虚拟表(非真实存在) 是跑在内存中的表,真实表是在硬盘上的表 使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去 ...
- Python11/26--mysql之视图/触发器/事务/存储过程
视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次用的时候直接使用即可 2.为什么用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何用视图 select * from ...
- mysql 视图 触发器 存储过程 函数事务 索引
mysql 视图 触发器 存储过程 函数事务 索引 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当 ...
随机推荐
- pthread创建线程的简单演示
使用pthread创建子线程的简单步骤 导入头文件 #import <pthread.h> 指定新线程标识符 使用pthread创建线程的函数 根据result = 0 与否判断子线程 ...
- [UWP]了解模板化控件(5.1):TemplatePart vs. VisualState
1. TemplatePart vs. VisualState 在前面两篇文章中分别使用了TemplatePart及VisualState的方式实现了相同的功能,其中明显VisualState的方式更 ...
- (三)训练HMM模块
“(二)杂项准备"之后,我们就已经训练了一个hmm模型了——“hmm0”. 接下来,我们将以“hmm0”作为基础,一路训练到“hmm7". 1.从“hmm0"训练到&qu ...
- CASE WHEN 及 SELECT CASE WHEN的用法(转)
Case具有两种格式.简单Case函数和Case搜索函数. 简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END ...
- .NET平台微服务项目汇集
最近博客园出现了一篇文章<微服务时代之2017年五军之战:Net PHP谁先死>,掀起了一波撕逼,作者只是从一个使用者的角度来指点江山,这个姿势是不对的..NET Core就是专门针对模块 ...
- 线性代数-矩阵-【2】矩阵生成 C和C++实现
矩阵的知识点之多足以写成一本线性代数. 所以我们把矩阵的运算封装成矩阵类.以C++为主进行详解. 点击这里可以跳转至 [1]矩阵汇总:http://www.cnblogs.com/HongYi-Lia ...
- python在windows和linux环境的进程对比
1.fork进程:(1)在windows系统中不可以用fork来创建进程,linux可以,但是创建大量进程使用很不方便. 2.Process进程: import multiprocessing as ...
- 广度优先搜索(BFS)——迷宫的最短路径
宽度优先搜索按照距开始状态由近到远的顺序进行搜索,因此可以很容易的用来求最短路径,最少操作之类问题的答案. 宽度优先搜索介绍(一篇不错的文章). 题目描述: 给定一个大小为N*M的迷宫.迷宫有通道和墙 ...
- JavaScript中事件
JS中的事件 一.事件分类: 鼠标事件:鼠标单击.鼠标双击.鼠标指上等... HTML事件:文档加载.焦点.表单提交等... 键盘事件:键盘按下(keydown).键盘按下并松开瞬间(keypress ...
- C语言运算符运算顺序判断实例1
程序1 #include <stdio.h> int main(void) { , j = , k = ; printf("%d\n", --j > i & ...