视图、触发器、事务(了解知识点),存储过程(重点)
1.视图
强调
1、字段名不能重复
2、视图是为了简化查询的sql语句,不应该修改视图中的记录
create view emp2dep as select emp.*,dep.name as dep_name from emp inner join dep on emp.dep_id = dep.id;
注意:
1. 使用视图以后就无需每次都重写子查询的sql,但是这么效率并不高,还不如我们写子查询的效率高 2. 而且有一个致命的问题:视图是存放到数据库里的,如果我们程序中的sql过分依赖于数据库中存放的视图,那么意味着,一旦sql需要修改且涉及到视图的部分,
则必须去数据库中进行修改,而通常在公司中数据库有专门的DBA负责,你要想完成修改,必须付出大量的沟通成本DBA可能才会帮你完成修改,极其地不方便。
2.触发器
1 CREATE TABLE cmd (
2 id INT PRIMARY KEY auto_increment,
3 USER CHAR (32),
4 priv CHAR (10),
5 cmd CHAR (64),
6 sub_time datetime, # 提交时间
7 success enum ('yes', 'no') #no代表执行失败,执行失败就会切换到errlog
8 );
9
10 CREATE TABLE errlog (
11 id INT PRIMARY KEY auto_increment,
12 err_id int
13 );
14
15 delimiter $$ # 每插入一行操作,触发器都会检测一次,如果success为no把为no的id传进去
16 CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
17 BEGIN
18 if NEW.success = 'no' then
19 insert into errlog(err_id) values(NEW.id);
20 end if;
21 END $$
22 delimiter ;
23
24 INSERT INTO cmd (
25 USER,
26 priv,
27 cmd,
28 sub_time,
29 success
30 )
31 VALUES
32 ('egon','0755','ls -l /etc',NOW(),'yes'),
33 ('egon','0755','cat /etc/passwd',NOW(),'no'),
34 ('egon','0755','useradd xxx',NOW(),'no'),
35 ('egon','0755','ps aux',NOW(),'yes');
3.事物
1 #transaction:事务,交易
2 # 事务可以包含一系列的sql语句,事务的执行具有原子性
3 #1、原子性:
4 #包含多条sql语句要么都执行成功,要么都执行不成功
5 #2、回滚
6
7 create table user(
8 id int primary key auto_increment,
9 name char(32),
10 balance int
11 );
12
13 insert into user(name,balance)
14 values
15 ('wsb',1000),
16 ('egon',1000),
17 ('ysb',1000);
18
19
20 start transaction;
21 try:
22 update user set balance=930 where id=1;
23 update user set balance=1010 where id=2;
24 update user set balance=1090 where id=3;
25 commit;
26 except Exception:
27 rollback();
4.存储过程
方案一:
应用程序:调用存储过程
mysql:编写存储过程
方案二:
应用程序:原生sql,纯sql语句
mysql:
方案三:
应用程序:ORM(类/对象 --->本质还是原生sql)
mysql:
执行效率:
方案一 > 方案二 -> 方案三
开发效率:
方案一 > 方案三 -> 方案二
无参存储过程
1 # 无参
2 delimiter $$
3 create procedure p1()
4 BEGIN
5 select * from blog;
6 END $$
7 delimiter ;
8
9 create table s1(
10 id int,
11 name varchar(20),
12 gender char(6),
13 email varchar(50)
14 );
15
16 delimiter $$
17 create procedure p2()
18 BEGIN
19 declare n int default 1;
20 while (n < 100) do
21 insert into s1 values(n,concat('egon',n),'male',concat('egon',n,'@163.com'));
22 set n=n+1;
23 end while;
24 END $$
25 delimiter ;
有参存储过程
1 # 有参
2 delimiter $$
3 create procedure p3(
4 in n int,
5 out res int
6 )
7 BEGIN
8 select * from blog where id > n;
9 set res = 0;
10 END $$
11 delimiter ;
12
13 # 直接在mysql中调用:
14 mysql> set @x=111;
15 mysql> call p3(3,@x);
16 mysql> select @x;
17 +------+
18 | @x |
19 +------+
20 | 0 |
21 +------+
22 1 row in set (0.00 sec)
23
24
25 # 在python中调用:
26 cursor.callproc('p4',(3,111)) #set @_p4_0 = 3; set @_p4_1 = 111
27 print(cursor.fetchall())
28 cursor.execute('select @_p4_1;')
29 print(cursor.fetchone())
在python中完整调用
1 import pymysql
2
3 client=pymysql.connect(
4 host='127.0.0.1',
5 port=3306,
6 user='root',
7 password='egon123',
8 database='db5',
9 charset='utf8'
10 )
11
12 cursor=client.cursor(pymysql.cursors.DictCursor)
13 res=cursor.callproc('p4',(3,111)) #set @_p4_0 = 3; set @_p4_1 = 111
14 # print(res)
15
16 print(cursor.fetchall())
17
18 cursor.execute('select @_p4_1;')
19 print(cursor.fetchone())
20
21 cursor.close()
22 client.close()
越是困难的事越要立即去做,这样收益才会最大!!!