1、视图python
视图是一个虚拟表(非真实存在),其本质是【根据SQL语句获取动态的数据集,并为其命名】,用户使用时只需使用【名称】便可获取结果集,能够将该结果集当作表来使用。mysql
使用视图咱们能够把查询过程当中的临时表摘出来,用视图去实现,这样之后再想操做该临时表的数据时就无需重写复杂的sql了,直接去视图中查找便可,但视图有明显地效率问题,而且视图是存放在数据库中的,若是咱们程序中使用的sql过度依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,所以并不推荐使用程序员
一、建立视图sql
语法:CREATE VIEW 视图名称 AS SQL语句数据库
create view teacher_view as select tid from teacher where tname='李平老师';网络
!!!注意注意注意:ide
1)使用视图之后就无需每次都重写子查询的sql,可是这么效率并不高,还不如咱们写子查询的效率高函数
2)并且有一个致命的问题:视图是存放到数据库里的,若是咱们程序中的sql过度依赖于数据库中存放的视图,那么意味着,一旦sql须要修改且涉及到视图的部分,则必须去数据库中进行修改,而一般在公司中数据库有专门的DBA负责,你要想完成修改,必须付出大量的沟通成本DBA可能才会帮你完成修改,极其地不方便。oop
二、使用视图fetch
修改视图,原始表也跟着改
create view course_view as select * from course; #建立表course的视图
select * from course_view;
update course_view set cname='xxx'; #更新视图中的数据
insert into course_view values(5,'yyy',2); #往视图中插入数据
select * from course; #发现原始表的记录也跟着修改了
注:通常状况下不该该修改视图中的记录,并且在涉及多个表的状况下是根本没法修改视图中的记录
三、修改视图
语法:ALTER VIEW 视图名称 AS SQL语句 (alter 变动)
alter view teacher_view as select * from course where cid>3;
四、删除视图
语法:DROP VIEW 视图名称
DROP VIEW teacher_view
2、触发器
使用触发器能够定制用户对表进行【增、删、改】操做时先后的行为。注意:没有查询!!!
一、建立触发器
插入前
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 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
特别的:NEW表示即将插入的数据行,OLD表示即将删除的数据行。
二、使用触发器
触发器没法由用户直接调用,而知因为对表的【增/删/改】操做被动引起的。
三、删除触发器
drop trigger tri_after_insert_cmd;
3、事务
事务用于将某些操做的多个SQL做为原子性操做,一旦有某一个出现错误,便可回滚到原来的状态,从而保证数据库数据完整性。
create table user(
id int primary key auto_increment,
name char(32),
balance int
);
insert into user(name,balance)
values
('wsb',1000),
('egon',1000),
('ysb',1000);
#原子操做
start transaction;
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='ysb'; #卖家拿到90元
commit;
#出现异常,回滚到初始状态
start transaction;
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
uppdate user set balance=1090 where name='ysb'; #卖家拿到90元,出现异常没有拿到
rollback;
commit;
mysql> select * from user;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | wsb | 1000 |
| 2 | egon | 1000 |
| 3 | ysb | 1000 |
+----+------+---------+
4、存储过程
一、介绍
存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,经过调用它的名字能够执行其内部的一堆sql
使用存储过程的优势:
1)用于替代程序写的SQL语句,实现程序与sql解耦
2)基于网络传输,传别名的数据量小,而直接传sql数据量大
使用存储过程的缺点:
1)程序员扩展功能不方便
补充:程序与数据库结合使用的三种方式
方式一:
MySQL:存储过程
程序:调用存储过程
方式二:
MySQL:
程序:纯SQL语句
方式三:
MySQL:
程序:类和对象,即ORM(本质仍是纯SQL语句)
二、建立简单存储过程(无参)
delimiter //
create procedure p1()
BEGIN
select * from blog;
INSERT into blog(name,sub_time) values("xxx",now());
END //
delimiter ;
在mysql中调用: call p1()
在python中基于pymysql调用
cursor.callproc('p1')
print(cursor.fetchall())
三、建立存储过程(有参)
对于存储过程,能够接收参数,其参数有三类:
in 仅用于传入参数用
out 仅用于返回值用
inout 既能够传入又能够看成返回值
四、执行存储过程
-- 无参数:call proc_name()
-- 有参数,全in:call proc_name(1,2)
-- 有参数,有in,out,inout
set @t1=0;
set @t2=3;
call proc_name(1,2,@t1,@t2)
五、删除存储过程
drop procedure proc_name;
五 函数
MySQL中提供了许多内置函数
一、自定义函数
注意:函数中不要写sql语句(不然会报错),函数仅仅只是一个功能,是一个在sql中被应用的功能
若要想在begin...end...中写sql,请用存储过程
二、删除函数
三、执行函数
6、流程控制
一、条件语句
if条件语句
delimiter //
CREATE PROCEDURE proc_if ()
BEGIN
declare i int default 0;
if i = 1 THEN
SELECT 1;
ELSEIF i = 2 THEN
SELECT 2;
ELSE
SELECT 7;
END IF;
END //
delimiter ;
二、循环语句
while循环
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN
DECLARE num INT ;
SET num = 0 ;
WHILE num < 10 DO
SELECT
num ;
SET num = num + 1 ;
END WHILE ;
END //
delimiter ;
repeat循环
delimiter //
CREATE PROCEDURE proc_repeat ()
BEGIN
DECLARE i INT ;
SET i = 0 ;
repeat
select i;
set i = i + 1;
until i >= 5
end repeat;
END //
delimiter ;
loop
BEGIN
declare i int default 0;
loop_label: loop
set i=i+1;
if i<8 then
iterate loop_label;
end if;
if i>=10 then
leave loop_label;
end if;
select i;
end loop loop_label;
END