mysql七:視圖、觸發器、事務、存儲過程、函數

1、視圖python

視圖是一個虛擬表(非真實存在),其本質是【根據SQL語句獲取動態的數據集,併爲其命名】,用戶使用時只需使用【名稱】便可獲取結果集,能夠將該結果集當作表來使用。mysql

    使用視圖咱們能夠把查詢過程當中的臨時表摘出來,用視圖去實現,這樣之後再想操做該臨時表的數據時就無需重寫複雜的sql了,直接去視圖中查找便可,但視圖有明顯地效率問題,而且視圖是存放在數據庫中的,若是咱們程序中使用的sql過度依賴數據庫中的視圖,即強耦合,那就意味着擴展sql極爲不便,所以並不推薦使用程序員


一、建立視圖sql

語法:CREATE VIEW 視圖名稱 AS  SQL語句數據庫

    create view teacher_view as select tid from teacher where tname='李平老師';網絡

!!!注意注意注意:ide

1)使用視圖之後就無需每次都重寫子查詢的sql,可是這麼效率並不高,還不如咱們寫子查詢的效率高函數

2)並且有一個致命的問題:視圖是存放到數據庫裏的,若是咱們程序中的sql過度依賴於數據庫中存放的視圖,那麼意味着,一旦sql須要修改且涉及到視圖的部分,則必須去數據庫中進行修改,而一般在公司中數據庫有專門的DBA負責,你要想完成修改,必須付出大量的溝通成本DBA可能纔會幫你完成修改,極其地不方便。oop

二、使用視圖fetch

修改視圖,原始表也跟着改

    create view course_view as select * from course; #建立表course的視圖

    select * from course_view;

    update course_view set cname='xxx'; #更新視圖中的數據

    insert into course_view values(5,'yyy',2); #往視圖中插入數據

    select * from course; #發現原始表的記錄也跟着修改了

注:通常狀況下不該該修改視圖中的記錄,並且在涉及多個表的狀況下是根本沒法修改視圖中的記錄

三、修改視圖

語法:ALTER VIEW 視圖名稱 AS SQL語句 (alter 變動)

     alter view teacher_view as select * from course where cid>3;

四、刪除視圖

語法:DROP VIEW 視圖名稱

     DROP VIEW teacher_view


2、觸發器

使用觸發器能夠定製用戶對錶進行【增、刪、改】操做時先後的行爲。注意:沒有查詢!!!

一、建立觸發器

    插入前

        CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW

        BEGIN

            ...

        END

    插入後

        CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW

        BEGIN

            ...

        END

    刪除前

        CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW

        BEGIN

            ...

        END

    刪除後

        CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW

        BEGIN

            ...

        END

    更新前

        CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW

        BEGIN

            ...

        END

    更新後

        CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW

        BEGIN

            ...

        END

舉個栗子:

    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

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

二、使用觸發器

    觸發器沒法由用戶直接調用,而知因爲對錶的【增/刪/改】操做被動引起的。

三、刪除觸發器

    drop trigger tri_after_insert_cmd;


3、事務

事務用於將某些操做的多個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元

    commit;


    #出現異常,回滾到初始狀態

    start transaction;

    update user set balance=900 where name='wsb'; #買支付100元

    update user set balance=1010 where name='egon'; #中介拿走10元

    uppdate user set balance=1090 where name='ysb'; #賣家拿到90元,出現異常沒有拿到

    rollback;

    commit;

    mysql> select * from user;

    +----+------+---------+

    | id | name | balance |

    +----+------+---------+

    |  1 | wsb  |    1000 |

    |  2 | egon |    1000 |

    |  3 | ysb  |    1000 |

    +----+------+---------+


4、存儲過程

一、介紹

存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,經過調用它的名字能夠執行其內部的一堆sql

使用存儲過程的優勢:

    1)用於替代程序寫的SQL語句,實現程序與sql解耦

    2)基於網絡傳輸,傳別名的數據量小,而直接傳sql數據量大

使用存儲過程的缺點:

    1)程序員擴展功能不方便

補充:程序與數據庫結合使用的三種方式

方式一:

    MySQL:存儲過程

    程序:調用存儲過程

方式二:

    MySQL:

    程序:純SQL語句

方式三:

    MySQL:

    程序:類和對象,即ORM(本質仍是純SQL語句)

二、建立簡單存儲過程(無參)

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


三、建立存儲過程(有參)

對於存儲過程,能夠接收參數,其參數有三類:

    in          僅用於傳入參數用

    out        僅用於返回值用

    inout     既能夠傳入又能夠看成返回值


四、執行存儲過程

    -- 無參數:call proc_name()

    -- 有參數,全in:call proc_name(1,2)

    -- 有參數,有in,out,inout

    set @t1=0;

    set @t2=3;

    call proc_name(1,2,@t1,@t2)

五、刪除存儲過程

    drop procedure proc_name;


五 函數

MySQL中提供了許多內置函數

一、自定義函數

注意:函數中不要寫sql語句(不然會報錯),函數僅僅只是一個功能,是一個在sql中被應用的功能

     若要想在begin...end...中寫sql,請用存儲過程

二、刪除函數


三、執行函數


6、流程控制

一、條件語句

if條件語句

    delimiter //

    CREATE PROCEDURE proc_if ()

    BEGIN

        

        declare i int default 0;

        if i = 1 THEN

            SELECT 1;

        ELSEIF i = 2 THEN

            SELECT 2;

        ELSE

            SELECT 7;

        END IF;

    END //

    delimiter ;

二、循環語句

while循環

    delimiter //

    CREATE PROCEDURE proc_while ()

    BEGIN


        DECLARE num INT ;

        SET num = 0 ;

        WHILE num < 10 DO

            SELECT

                num ;

            SET num = num + 1 ;

        END WHILE ;

    END //

    delimiter ;

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 ;

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

相關文章
相關標籤/搜索