python 之 數據庫(視圖、觸發器、事務、存儲過程)


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代碼...
endcreate 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代碼...
endcreate 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代碼...
endcreate 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 |
+----+-----------------+---------------------+
View Code

刪除觸發器:

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())
View Code

10.162 刪除存儲過程

drop procedure proc_name;

回到頂部


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM