Python Day48 mysql補充

來源:互聯網
上載者:User

標籤:local   觸發器   fetch   0.00   複雜   exe   har   pass   let   

一、視圖

  視圖是一個虛擬表(非真實存在),其本質是【根據SQL語句擷取動態資料集,並為其命名】,使用者使用時只需使用【名稱】即可擷取結果集,可以將該結果集當做表來使用。使用視圖我們可以把查詢過程中的暫存資料表摘出來,用視圖去實現,這樣以後再想操作該暫存資料表的資料時就無需重寫複雜的sql了,直接去視圖中尋找即可,但視圖有明顯地效率問題,並且視圖是存放在資料庫中的,如果我們程式中使用的sql過分依賴資料庫中的視圖,即強耦合,那就意味著擴充sql極為不便,因此並不推薦使用。

1、建立視圖

create  view 視圖名 as sql語句

  注意,上述為建立視圖的語句,但是語句中的sql語句中不能包含子查詢。執行個體如下:

  可以通過建立視圖的方式,將上述sql查詢語句的結果儲存成視圖形式的虛擬表,下次再次使用時,就可以避免上述重複的sql語句:

2、視圖的修改

  正如視圖概念中所述,視圖為sql語句查詢結果的虛擬表,它的真實資料是來源sql語句中涉及的真正的表中,當sql語句中只關聯一個表,更改視圖中的資料,所被關聯的表中的資料也會跟著更改,顯然這是不合理的,當sql語句中關聯多個表,則壓根不可以實現對視圖中的資料的更改。總之不可以通過update或者insert等語句對視圖中的內容變更。如果想真正的實現對視圖的更改,其實就是更改原有視圖中的sql語句,具體的更改文法如下:

alter view 原視圖名 as 新sql語句 

3、刪除視圖

drop view 視圖名      #例:drop view course_teacher

  總結:使用視圖以後就無需每次都重寫子查詢的sql,但是這麼效率並不高,還不如我們寫子查詢的效率高;其次視圖是存放到資料庫裡的,如果我們程式中的sql過分依賴於資料庫中存放的視圖,那麼意味著,一旦sql需要修改且涉及到視圖的部分,則必須去資料庫中進行修改。

二、觸發器

  使用觸發器可以定製使用者對錶進行【增、刪、改】操作時前後的行為,注意:沒有查詢

1、建立觸發器文法

# 插入前CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROWBEGIN    ...END# 插入後CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROWBEGIN    ...END# 刪除前CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROWBEGIN    ...END# 刪除後CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROWBEGIN    ...END# 更新前CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROWBEGIN    ...END# 更新後CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROWBEGIN    ...END

2、觸發器執行個體

#準備表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 ROWBEGIN    IF NEW.success = ‘no‘ THEN #等值判斷只有一個等號            INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必須加分號      END IF ; #必須加分號END//delimiter ;#往表cmd中插入記錄,觸發觸發器,根據IF的條件決定是否插入錯誤記錄檔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 |+----+-----------------+---------------------+rows in set (0.00 sec)

  特別的:NEW表示即將插入的資料行,OLD表示即將刪除的資料行。

 3、觸發器的刪除

  觸發器無法由使用者直接調用,而是由於對錶的【增/刪/改】操作被動引發的。刪除觸發器的文法如下:

drop trigger 觸發器名;  #例:drop trigger tri_after_insert_cmd;

三、事務

  事務用於將某些操作的多個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‘; update user set balance=1010 where name=‘egon‘; update user set balance=1090 where name=‘ysb‘; commit;#出現異常,復原到初始狀態start transaction;update user set balance=800 where name=‘wsb‘; update user set balance=1020 where name=‘egon‘; uppdate user set balance=1180 where name=‘ysb‘; rollback;  
commit;

四、預存程序

  預存程序包含了一系列可執行檔sql語句,預存程序存放於MySQL中,通過調用它的名字可以執行其內部的一堆sql。使用預存程序的優點:(1)用於替代程式寫的SQL語句,實現程式與sql解耦;(2)基於網路傳輸,傳別名的資料量小,而直接傳sql資料量大。缺點是程式員擴充功能不方便。

1、資料庫與程式使用方式

#方式一:    MySQL:預存程序    程式:調用預存程序#方式二:    MySQL:    程式:純SQL語句#方式三:    MySQL:    程式:類和對象,即ORM(本質還是純SQL語句)

2、建立無參數預存程序

#建立無參預存程序delimiter $$                             #符號不局限於此,但前後需一致create procedure p1()begin    declare i int default 1;    while (i<10) do        select * from course;        set i=i+1;    end while;end $$delimiter ;#調用預存程序call p1();

 

3、建立有參數預存程序

  有參數的情況時,在定義預存程序中必須定義參數的類型,包含三種,解釋如下:

#in          僅用於傳入參數用#out         僅用於傳回值用#inout       既可以傳入又可以當作傳回值

  應用執行個體:

#建立有參預存程序delimiter $$create procedure p2(    in x char(5),    out y int)begin    select cid from course where cname=x;    set y=1;end $$delimiter ;#mysql中調用:set @x=‘生物‘;set @y=0;call p2(@x,@y);#查看傳回值select @y;#pymysql中的調用:import pymysqlconn=pymysql.connect(    host=‘localhost‘,    port=3306,    user=‘root‘,    password=‘‘,    database=‘day48‘,    charset=‘utf8‘   )cur=conn.cursor()#拿到預存程序sql語句的執行結果cur.callproc(‘p2‘,(‘生物‘,0))print(cur.fetchall())
#拿到預存程序傳回值‘‘‘pymysql預設會把參數變為如下形式名字,分別為生物和0的名字:@_p2_0 ,@_p2_1;‘‘‘cur.execute(‘select @_p2_1;‘)print(cur.fetchone())cur.close()conn.close()

  帶事務預存程序執行個體:

#介紹delimiter //            create procedure p4(                out status int            )            BEGIN                1. 聲明如果出現異常則執行{                    set status = 1;                    rollback;                }                                   開始事務                    -- 由秦兵賬戶減去100                    -- 方少偉賬戶加90                    -- 張根賬戶加10                    commit;                結束                                set status = 2;                                            END //            delimiter ;#實現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())

4、刪除預存程序

drop procedure proc_name;

Python Day48 mysql補充

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.