10.13 視圖
1、什么是視圖 視圖就是通過查詢得到一張虛擬表,然后保存下來,下次用的直接使用即可
2、為什么要用視圖 如果要頻繁使用一張虛擬表,可以不用重復查詢
3、如何使用視圖
視圖記錄的增、刪、改和表方法相同,但改變視圖記錄,原始表也跟着改,所以不要修改視圖記錄,只用於查看
create view teacher2course as #創建視圖 select * from teacher inner join course on teacher.tid = course.teacher_id; alter view teacher2course as #修改視圖名 select * from teacher inner join course on teacher.tid = course.teacher_id; drop view teacher2course; #刪除視圖
強調: 1、在硬盤中,視圖只有表結構文件,沒有表數據文件 2、視圖通常用於查詢,盡量不要修改視圖中的數據
10.14 觸發器
觸發器:在滿足對某張表數據的增、刪、改的情況下,自動觸發的功能稱之為觸發器 觸發器專門針對我們對某一張表數據增insert、刪delete、改update的行為,這類行為一旦執行就會觸發觸發器的執行,即自動運行另外一段sql代碼
創建觸發器語法:
# 針對插入(insert) create trigger tri_after_insert_t1 after insert on 表名 for each row begin sql代碼... end create trigger tri_before_insert_t2 before insert on 表名 for each row begin sql代碼... end # 針對刪除(delete) create trigger tri_after_delete_t1 after delete on 表名 for each row begin sql代碼... end create trigger tri_before_delete_t2 before delete on 表名 for each row begin sql代碼... end # 針對修改(update) create trigger tri_after_update_t1 after update on 表名 for each row begin sql代碼... end create trigger tri_before_update_t2 before update on 表名 for each row begin sql代碼... end
舉例:

CREATE TABLE cmd ( id INT PRIMARY KEY auto_increment, USER CHAR (32), priv CHAR (10), cmd CHAR (64), sub_time datetime, #提交時間 success enum ('yes', 'no') ); CREATE TABLE errlog ( id INT PRIMARY KEY auto_increment, err_cmd CHAR (64), 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 ; insert into cmd (USER,priv,cmd,sub_time,success) values ('egon','0755','ls -l /etc',NOW(),'yes'), ('egon','0755','cat /etc/passwd',NOW(),'no'), ('egon','0755','useradd xxx',NOW(),'no'), ('egon','0755','ps aux',NOW(),'yes'); mysql> select * from errlog; #查詢錯誤日志,發現有兩條 +----+-----------------+---------------------+ | id | err_cmd | err_time | +----+-----------------+---------------------+ | 1 | cat /etc/passwd | 2017-09-14 22:18:48 | | 2 | useradd xxx | 2017-09-14 22:18:48 | +----+-----------------+---------------------+
刪除觸發器:
drop trigger tri_after_insert_cmd;
10.15 事務
什么是事務: 開啟一個事務可以包含一些sql語句,這些sql語句要么同時成功,要么都不成功,稱之為事務的原子性 作用:事務用於將某些操作的多個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元,出現異常沒有拿到 rollback; #出現異常,回滾到初始狀態 commit; #無異常,提交結果,提交后回滾無效
10.16 存儲過程
存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,通過調用它的名字可以執行其內部的一堆sql
存儲過程的優點:1、用於替代程序寫的SQL語句,實現程序與sql解耦 2、基於網絡傳輸,傳別名的數據量小,而直接傳sql數據量大
存儲過程的缺點:程序員擴展功能不方便
10.161 創建與執行存儲過程
創建簡單存儲過程(無參):
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())
創建存儲過程(有參):
delimiter $$ create procedure p2( in m int, #只可傳入 in n int, out res int) #只可返回 # inout 既可以傳入又可以當作返回值 begin select tname from teacher where tid > m and tid < n; set res=1; #執行成功res返回0 end $$ delimiter ; #在mysql中調用 set @res=0; call p2(3,2,@res) select @res; #0代表假(執行失敗),1代表真(執行成功) #在python中基於pymysql調用 cursor.callproc('p2',(2,3,0)) #0相當於set @res=0 print(cursor.fetchall()) #查詢select的查詢結果 cursor.execute('select @_p2_2;') #@_p2_2代表第三個參數,即返回值 print(cursor.fetchall())
將事務封裝入存儲過程:

delimiter // create PROCEDURE p5( OUT p_return_code tinyint ) BEGIN DECLARE exit handler for sqlexception BEGIN -- ERROR set p_return_code = 1; rollback; END; DECLARE exit handler for sqlwarning BEGIN -- WARNING set p_return_code = 2; rollback; END; START TRANSACTION; DELETE from tb1; #執行失敗 insert into blog(name,sub_time) values('yyy',now()); COMMIT; -- SUCCESS set p_return_code = 0; #0代表執行成功 END // delimiter ; #在mysql中調用存儲過程 set @res=123; call p5(@res); select @res; #在python中基於pymysql調用存儲過程 cursor.callproc('p5',(123,)) print(cursor.fetchall()) #查詢select的查詢結果 cursor.execute('select @_p5_0;') print(cursor.fetchall())
10.162 刪除存儲過程
drop procedure proc_name;