視圖,觸發器,事務,存儲過程,函數,流程控制,
阿新 • • 發佈:2018-05-14
部門 ces fault PE time into 事務 sele else
一,視圖
1,什麽是視圖?
視圖就是通過查詢得到一張虛擬表,然後保存下來,下次用的話直接使用即可
2,為什麽要用視圖
如果要頻繁使用一張虛擬表,可以不用重復查詢
3,怎麽用?
在查詢前面加 create view 視圖名稱 as sql語句
create view teacher_view as select tid from teacher where tname=‘李平老師‘;
強調:在硬盤中,視圖只有表結構文件,沒有數據文件
視圖開發盡量不用 因為是在mysql裏面 ,視圖通常用於插敘,盡量不要修改視圖中的數據
2,修改視圖:alter view 視圖名稱 as sql語句
3,刪除視圖:drop view 視圖名稱
二,觸發器
1,觸發器
在滿足對某張表增刪改的情況下,自動觸發的功能稱之為觸發器 註意:沒有查詢
2,為什麽用觸發器
觸發器專門針對我們對某一張表數據增insert,刪delete,改update的行為,這類行為一旦執行
就會觸發觸發器的執行,即自動運行另外一段sql代碼
3,創建觸發器語法
create trigger tril after 針對插入 create trigger tri_after_insert_t1 after insert on 表名 for each row begin sql 代碼。 end create trigger tri_after_insert_t2 before insert on 表名for each row begin sql代碼。。 end 針對刪除 create trigger tri_after_delete_t1 after on 表名 for each row begin sql代碼。。。 end create trigger tri_after_delete_t2 before delete on 表名 for each row begin sql代碼。。。 end # 針對修改 create trigger tri_after_update_t1 after update on 表名 for each row begin sql代碼。。。 end create trigger tri_after_update_t2 before update on 表名for each row begin sql代碼。。。 end 04 案例 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‘) #0代表執行失敗 ); 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 ; drop trigger tri_after_insert_cmd;
觸發器的兩個關鍵字:new ,old
-- new :表示新的記錄
-- old:表示舊的那條記錄
-- 什麽情況下才往裏面插記錄
-- 當命令輸入錯誤的時候就把錯誤的記錄插入到err_log表中
三,事務(重重重)
1,什麽是事務?
開啟一個事務可以包含一些sql語句要麽同時成功,這些sql語句要麽成功
要麽一個都別想成功,稱為事務的原子性·
2,事務的作用
務用於將某些操作的多個SQL作為原子性操作,一旦有某一個出現錯誤,
即可回滾到原來的狀態,從而保證數據庫數據完整性。
事務也就是要麽都成功,要麽都不成功
事務就是由一堆sql語句組成的
3,如何用?
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); try: update user set balance=900 where name=‘wsb‘; update user set balance=1010 where name=‘egon‘; update user set balance=1090 where name=‘ysb‘; except 異常: rollback; else: commit; 如果都成功就執行commit,,,如果不成功就執行rollback。 rollback; #如果任意一條sql出現異常,都應該回歸到初始狀態
四,存儲過程(重重重)
1,存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,通過調用它的名字可以執行其內部的一堆sql 存儲過程的優點: 1.程序與數據實現解耦 2.減少網絡傳輸的數據量 但是看似很完美,還是不推薦你使用 Mysql當中的函數不能單獨調用 表豎著顯示\G 2, 三種開發模型 1、 應用程序:只需要開發應用程序的邏輯 mysql:編寫好存儲過程,以供應用程序調用 優點:開發效率,執行效率都高 缺點:考慮到人為因素、跨部門溝通等問題,會導致擴展性差 2、 應用程序:除了開發應用程序的邏輯,還需要編寫原生sql mysql: 優點:比方式1,擴展性高(非技術性的) 缺點: 1、開發效率,執行效率都不如方式1 2、編寫原生sql太過於復雜,而且需要考慮到sql語句的優化問題 3、 應用程序:開發應用程序的邏輯,不需要編寫原生sql,基於別人編寫好的框架來處理數據,ORM mysql: 優點:不用再編寫純生sql,這意味著開發效率比方式2高,同時兼容方式2擴展性高的好處 缺點:執行效率連方式2都比不過 03 創建存儲過程 delimiter $$ create procedure p1( in m int, in n int, out res int ) begin select tname from teacher where tid > m and tid < n; set res=0; end $$ delimiter ; # 如何用存儲過程 #1、直接在mysql中調用 set @res=10 call p1(2,4,10); #查看結果 select @res; #2、在python程序中調用 #3、事務的使用 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; update user set balance=900 where id =1; update user123 set balance=1010 where id = 2; update user set balance=1090 where id =3; COMMIT; -- SUCCESS set p_return_code = 0; #0代表執行成功 END // delimiter ; delimiter // create PROCEDURE p6( 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; update user set balance=900 where id =1; update user set balance=1010 where id = 2; update user set balance=1090 where id =3; COMMIT; -- SUCCESS set p_return_code = 0; #0代表執行成功 END // delimiter ; 4,在python 中調用存儲過程 # import pymysql # # conn=pymysql.connect( # host=‘127.0.0.1‘, # port=3306, # user=‘root‘, # password=‘123‘, # charset=‘utf8‘, # database=‘db42‘ # ) # # cursor=conn.cursor(pymysql.cursors.DictCursor) # # cursor.callproc(‘p1‘,(2,4,10)) #@_p1_0=2,@_p1_1=4,@_p1_2=10 # # # print(cursor.fetchall()) # # cursor.execute(‘select @_p1_2;‘) # print(cursor.fetchone()) # # cursor.close() # conn.close() # import pymysql # # conn=pymysql.connect( # host=‘127.0.0.1‘, # port=3306, # user=‘root‘, # password=‘123‘, # charset=‘utf8‘, # database=‘db44‘ # ) # # cursor=conn.cursor(pymysql.cursors.DictCursor) # # cursor.callproc(‘p6‘,(100,)) #@_p5_0 = 100 # # cursor.execute(‘select @_p6_0‘) # print(cursor.fetchone()) # # cursor.close() # conn.close()
五,函數
1、強調:mysql內置的函數只能在sql語句中使用
mysql> select date_format(sub_time,‘%Y-%m‘),count(id) from blog group by date_format(sub_time,‘%Y-%m‘);
六,流程控制
1.條件語句 delimiter // create procedure proc_if() begin declare i int default 0; if i=1then select 1; elseif i = 2 then select 2; else select 7; end if; end // delimiter; 2,循環語句 delimiter // create procedure proc_while() being declare num int; set num = 0; where num<10 do SELECT num ; SET num = num + 1 ; END WHILE ; END // delimiter ; 3,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 ; 4,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 select case when name = ‘egon‘ then name when name = ‘alex‘ then concat(name,‘_BIGSB‘) else concat(name,‘_SB‘) end from emp;
視圖,觸發器,事務,存儲過程,函數,流程控制,