1. 程式人生 > >mysql-視圖、觸發器、事務、存儲過程、流程控制

mysql-視圖、觸發器、事務、存儲過程、流程控制

沖突 hid png -s name 新的 update pro def

目錄

  1. 視圖
  2. 觸發器
  3. 事務
  4. 存儲過程
  5. 流程控制

一、視圖

視圖是由查詢結果構成的一張虛擬表,和真實的表一樣,帶有名稱的列和行數據

強調:視圖是永久存儲的,但是視圖存儲的不是數據,只是一條sql語句

視圖的特點:

  1. 視圖的列可以來自不同的表,是表的抽象和邏輯意義上建立的新關系。
  2. 視圖是由基本表(實表)產生的表(虛表)。
  3. 視圖的建立和刪除不影響基本表。
  4. 對視圖內容的更新(添加、刪除和修改)直接影響基本表。
  5. 當視圖來自多個基本表時,不允許添加和刪除數據。

優點:

  1. 可以簡化查詢(多表查詢轉換為直接通過視圖查詢)
  2. 可以進行權限控制(把表的權限封閉,開發對應的視圖權限)

(一)、創建視圖

create view 視圖名稱  as sql 查詢語句  例子:CREATE view test_view as SELECT * from test;

(二)、查詢視圖

select * from 視圖名 [where 條件]

(三)、修改視圖

alter view 視圖名稱 AS SQL語句; 例子:ALTER view test_view as SELECT * from test_view WHERE salary>10000

(四)、刪除視圖

drop view 視圖名稱; 
例子:drop view test_view

二、觸發器

觸發器可以監視用戶對表的增、刪、改操作,並觸發某種操作(沒有查),自動執行,無法直接調用。

創建觸發器語法的四要素:

  1.監視地點(table)

  2.監視事件(insert/update/delete)

  3.觸發時間(before/after)

  4.觸發事件(insert/update/delete)

(一)、創建觸發器

技術分享圖片
# 插入前
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 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 ;


#往表cmd中插入記錄,觸發觸發器,根據IF的條件決定是否插入錯誤日誌
INSERT INTO cmd (
    USER,
    priv,
    cmd,
    sub_time,
    success
)
VALUES
    (A,0755,ls -l /etc,NOW(),yes),
    (A,0755,cat /etc/passwd,NOW(),no),
    (A,0755,useradd xxx,NOW(),no),
    (A,0755,ps aux,NOW(),yes);


#查詢錯誤日誌,發現有兩條
mysql> select * from errlog;
+----+-----------------+---------------------+
| id | err_cmd         | err_time            |
+----+-----------------+---------------------+
|  1 | cat /etc/passwd | 2018-09-18 20:18:48 |
|  2 | useradd xxx     | 2018-09-18 20:18:48 |
+----+-----------------+---------------------+
2 rows in set (0.00 sec)
案例

強調:NEW表示即將插入的數據行,OLD表示即將刪除的數據行

(二)、查看觸發器

show triggers

(三)、刪除觸發器

drop trigger 觸發器的名稱

三、事務

事務用於將某些操作的多個SQL作為原子性操作,意思就是,事務是一組sql語句集合。

一旦有某一個出現錯誤,即可回滾到原來的狀態,從而保證數據庫數據完整性。在事務內的語句, 要麽全部執行成功, 要麽全部執行失敗。

(一)、事務的特性

事務具有以下四個特性(ACID)

  1.原子性:事務是一個整體,不可分割,包含在其中的sql操作要麽全部成功,要麽全部失敗回滾,不可能只執行其中一部分操作。

  2.一致性:當事務執行後 所有的數據都是完整的(外鍵約束 非空約束)。

  3.持久性:一旦事務提交,數據永久保存在數據庫中

  4.隔離性:事務之間相互隔離,一個事務的執行不影響其他事務的執行

SQL標準定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的並發處理,並擁有更低的系統開銷。

(二)、事務的隔離級別

  1.READ UNCOMMITED(未提交讀):所有事務都可以看到其他未提交事務的執行結果。很少用於實際應用,因為它的性能不比其他級別好多少

  2.READ COMMITED(提交讀):大部分數據庫默認級別,不包括mysql。一個事務從開始到提交之前, 所做的任何修改對其他事務都是不可見的。

  3.REPEATABLE READ(可重復讀):mysql默認級別,解決了臟讀的問題. 該級別保證了在同一個事務中多次讀取同樣記錄的結果時一致的. 無法解決幻讀問題

  4.SERIALIZABLE(可串行化):是最高的隔離級別,強制事務排序,使之不可能相互沖突,從而解決幻讀問題

技術分享圖片

臟讀: 一個事物 讀到了 另一個事務未提交的數據 查詢 之前要保證 所有的更新都已經完成。

不可重復讀:在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的數據。

幻讀:指的是當某個事務在讀取某個範圍內的記錄時, 另外一個事務又在該範圍內插入了新的記錄, 當之前的事務再次讀取該範圍的記錄時, 會產生幻行(Phantom Row).

(三)、事務操作

start transaction; 開啟一個事物
commit 提交事物
rollback 回滾事務

註:mysql默認開啟自動提交事務,pymysql默認是不自動提交,需手動commit

四、存儲過程

存儲過程包含了一系列可執行的sql語句的集合,類似於函數(方法)。

使用存儲過程的優點:

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

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

缺點:不方便擴展

(一)、使用存儲過程

創建語法:
    create procedure 過程的名稱 ({in,out,inout}  數據類型 參數名稱)
    begin
        具體的sql代碼
    end
    參數前面需要指定參數的作用
in 表示該參數用於傳入數據 out 用於返回數據 inout 即可傳入 也可返回 參數類型是 mysql中的數據類型

調用語法:
  call 存儲過程()
技術分享圖片
         案例:創建一個存儲過程 作用是將兩個整數相加
            create procedure add_p (in a int,in b int)
            begin
                select a + b;
            end

            //
      調用 call add_p(1,2)

         案例:創建一個存儲過程 作用是將兩個整數相加 將結果保存在變量中
        定義一個變量
        set @su = 100;
            create procedure add_p2 (in a int,in b int,out su int)
            begin
                set su = a + b;
            end

            //
    
    定義變量 set @su = 100;
    調用過程 call  add_p2(10,20,@su);

          註意  在存儲過程中 需要使用分號來結束一行 但是分號有特殊含義
          得將原始的結束符 修改為其他符號
            delimiter // 結束符更換為//
            delimiter;
案列
在存儲過程中 需要使用分號來結束一行 但是分號有特殊含義
得將原始的結束符 修改為其他符號
      delimiter // 結束符更換為//
      delimiter;
技術分享圖片
    create procedure show_p (in a int)
    begin
    if a = 1 then
        select "壹";
    elseif a = 2 then
        select "貳";
    else
        select "other";
    end if;
    end //
使用存儲過程 完成 輸入 一個 數字 1或2 顯示 壹 或 貳

(二)、刪除存儲過程

drop procedure proc_name;

五、流程控制

(一)、條件語句

技術分享圖片
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 ;
if

(二)、循環語句

技術分享圖片
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 ;
while 技術分享圖片
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 ;
repeat 技術分享圖片
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
loop

mysql-視圖、觸發器、事務、存儲過程、流程控制