MySQL基礎筆記(6) - 遊標&觸發器&事務
阿新 • • 發佈:2021-10-20
本文為MySQL基礎入門相關筆記,同時參考了尚矽谷的BV1xW411u7ax網課和《MySQL必知必會》兩者,主要用於個人記錄與分享,如有錯誤歡迎留言指出
遊標&觸發器&事務
目錄1. 遊標
定義:有時需要在檢索出來的行中前進或後退一行/多行,這就是使用遊標的原因。遊標是一個被儲存在Mysql伺服器上的資料庫查詢,它是被該語句檢索出來的結果集。在儲存了遊標之後,應用程式可以根據需要滾動或遊覽其中的資料。Mysql的遊標只能用於儲存過程和函式
注意:建立語句均只能在命令列視窗執行,請先在命令列登入並轉到當前庫,然後再貼上進行操作
#1.建立遊標 DELIMITER // CREATE PROCEDURE processorders() BEGIN DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; END// #2.開關遊標 OPEN ordernumbers; CLOSE ordernumbers; #例項 DELIMITER // CREATE PROCEDURE processorders() BEGIN -- 定義三個變數 DECLARE done BOOLEAN DEFAULT 0; DECLARE o INT; DECLARE t DECIMAL(8,2); DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; -- 當沒有更多的行供repeat迴圈的時候,將done設定為1,停止迴圈 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1; -- 建立ordertotals表 CREATE TABLE IF NOT EXISTS ordertotals (order_num INT,total DECIMAL(8,2)); OPEN ordernumbers; -- 迴圈直到done不為0時停止 REPEAT -- 遊標結合repeat查看錶每一行並存入到變數o中 FETCH ordernumbers INTO o; -- ordertotal是上一章中用來統計商品總價格的儲存流程s CALL ordertotal(o,1,t); -- 將計算結果插入到新表ordertotals中 INSERT INTO ordertotals(order_num,total) VALUES(o,t); UNTIL done END REPEAT; CLOSE ordernumbers; END// SELECT * FROM ordertotals; #本例項跨度較大,重在理解
2. 觸發器
定義:觸發器是Mysql響應DELETE,INSERT,UPDATE語句而自動執行的一條/一組Mysql語句
2.1 觸發器的建立與刪除
-
建立觸發器
語法:
create trigger [觸發器名] [觸發時機] [觸發器響應的活動] ON [觸發器關聯的表]
CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT 'Product added' INTO @asd; #只有表才能支援觸發器,檢視不支援 #觸發器按每個表每個事件每次地定義,每個表每個事件每次只允許擁有一個觸發器。因此,每個表最多支援6個觸發器(每條insert,update,delete前後)。單一觸發器不能與多個事件或多個表關聯 #Mysql 5之後不允許觸發器直接返回值,這裡將返回值儲存到了變數asd中
-
刪除觸發器
DROP TRIGGER newproduct;
2.2 觸發器的使用
-
INSERT觸發器
- INSERT觸發器程式碼內,可以引用一個名為NEW的虛擬表,可以由此訪問那些被插入的行
- 在BEFORE INSERT觸發器中,NEW中的值也可以被更新(允許更改被插入的值)
- 對於AUTO_INCREMENT列,NEW在INSERT執行前包含0,在執行後包含新的自動生成的值
#例項 #設定一個觸發器,每當插入完成後,從new表中獲得order_num的新數值,然後儲存到asd中 CREATE TRIGGER neworder AFTER INSERT ON orders FOR EACH ROW SELECT new.order_num INTO @asd; INSERT INTO orders(order_date,cust_id) VALUES(NOW(),10001); SELECT @asd;
-
DELETE觸發器
-
DELETE觸發器程式碼內,可以引用一個名為OLD的虛擬表,訪問被刪除行
-
OLD的中的值全部都是隻讀的,不可更改
#例項 #設定一個觸發器,在刪除行前,將行的資料轉移到另一個臨時表中 CREATE TRIGGER deleteorder BEFORE DELETE ON orders FOR EACH ROW BEGIN INSERT INTO archive_orders(order_num,order_date,cust_id) VALUES(OLD.order_num,OLD.order_date,OLD.cust_id); END;
-
-
UPDATE觸發器
- UPDATE觸發器程式碼總,可以引用OLD的虛擬表訪問UPDATE之前的值,引用NEW的虛擬表訪問UPDATE後的值
- 在BEFORE UPDATE觸發器中,NEW中的值可能也被更新
- OLD中的值全都是隻讀的,不能更新
#例項 #設定一個觸發器,保證州名的縮寫總是大寫 CREATE TRIGGER updatevender BEFORE UPDATE ON vendors FOR EACH ROW SET NEW.vend_state = Upper(NEW,vend_state);
3. 事務
3.1 事務的使用
定義:事務是指一個或一組sql語句組成一個執行單元,這個執行單元要麼全部執行,要麼全部不執行。一個事務一旦執行失敗,就會回滾到上一個步驟。(MyISAM引擎不支援事務處理,一般使用InnoDB引擎)
特性(ACID):
- 原子性:一個事務不可再分割,要麼都執行要麼都不執行
- 一致性:一個事務執行會使資料從一個一致狀態切換到另一個一致狀態
- 隔離性:一個事物的執行不受其它事務的干擾
- 永續性:一個事務一旦提交,則會永久的改變資料庫的資料
事務的分類:
- 隱式事務:事務沒有明顯的開啟和結束的標記(比如insert,update,delete語句)
- 顯式事務:事務具有明顯的開啟和結束的標記(使用前必須設定自動提交功能為禁用)
#1.開啟事務
SET autocommit=0;
START TRANSACTION;
#2.編寫一組事務的語句
UPDATE account SET balance = 500;
UPDATE account SET balance = 1500;
#3.結束事務
COMMIT; #提交事務
#OR
ROLLBACK; #回滾
#4.savepoint的使用:savepoint一般搭配rollback使用,用於指定回滾的位置
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a; #設定儲存點
DELETE FROM account WHERE id=28;
ROLLBACK TO a; #回滾到儲存點
#在事務中,回滾可以對INSERT,UPDATE,DELETE生效,但是對CREATE,DROP,TRANSACTION無效
3.2 事務的隔離級別
事務的隔離級別/併發問題 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
read uncommitted | √ | √ | √ |
read committed | × | √ | √ |
repeatable read | × | × | √ |
serializable | × | × | × |
檢視隔離級別:select @@tx_isolation;
設定隔離級別:set session|global transaction isolation level 隔離級別;