MySQL命令學習筆記(七)

1 使用遊標

1.1 遊標

遊標(cursor)是一個存儲在MySQL服務器上的數據庫查詢,它不是一條SELECT語句,而是被該語句檢索出來的結果集。在存儲了遊標之後,應用程序可以根據需要滾動或瀏覽其中的數據。
遊標主要用於交互式應用,其中用戶需要滾動屏幕上的數據,並對數據進行瀏覽或做出更改。MySQL遊標只能用於存儲過程(和函數)。

1.2 使用遊標

使用遊標涉及幾個明確的步驟:

  • 在能夠使用遊標前,必須聲明(定義)它
  • 一旦聲明後,必須打開遊標以供使用,這個過程用前面定義的SELECT語句把數據實際檢索出來
  • 對於填有數據的遊標,根據需要取出(檢索)各行
  • 在結束遊標使用時,必須關閉遊標

1.2.1 創建遊標

遊標用DECLARE創建,DECLARE命名遊標,並定義相應的SELECT語句,根據需要帶WHERE和其他子句。示例如下:

DELIMITER //
CREATE PROCEDURE productorders()
BEGIN
    DECLARE ordernumbers CURSOR
    FOR
    SELECT quantity FROM table1;
END //
DELIMITER ;

DECLARE語句用來定義和命名遊標,這裏爲ordernumbers。== 存儲過程(類似函數)處理完成後,遊標就消失(因爲它侷限於存儲過程)==

1.2.2 打開和關閉遊標

遊標用OPEN CURSOR語句來打開:

OPEN ordernumbers;

在處理OPEN語句時執行查詢,存儲檢索出的數據以供瀏覽和滾動
遊標處理完成後,應當使用如下語句關閉遊標:

CLOSE ordernumbers;

CLOSE釋放遊標使用的所有內部內存和資源,因此在每個遊標不再需要時都應該關閉。

隱含關閉 若不明確關閉遊標,MySQL將會在到達END語句時自動關閉它
修改前面的示例:

DELIMITER //        #重新定義分隔符
CREATE PROCEDURE productorders()
BEGIN
    -- declare the cursor
    DECLARE ordernumbers CURSOR FOR SELECT quantity FROM table1;
    
    -- open the cursor
    OPEN ordernumbers;
    
    -- close the cursor
    CLOSE ordernumbers;
END //
DELIMITER ;       #重新定義分隔符

1.2.3 使用遊標數據

在一個遊標被打開後,可以使用FETCH語句分別訪問它的每一行。FETCH指定檢索什麼數據(所需的列),檢索出來的數據存儲在什麼地方。它還向前移動遊標中的內部行指針,使下一條FETCH句檢索下一行(不重複讀取同一行)。

示例1:從遊標中檢索單個行(第一行)

DELIMITER //        #重新定義分隔符
CREATE PROCEDURE productorders()
BEGIN
    -- declare local variables
    DECLARE o INT;
    
    -- declare the cursor
    DECLARE ordernumbers CURSOR FOR SELECT quantity FROM table1;
    
    -- open the cursor
    OPEN ordernumbers;
    
     -- get order number
    FETCH ordernumbers INTO o;
    
    -- close the cursor
    CLOSE ordernumbers;
END //
DELIMITER ;       #重新定義分隔符

其中FETCH用來檢索當前行的quantity列(將自動從第一行開始)到一個名爲o的局部聲明的變量中。對檢索出的數據不做任何處理。

2 使用觸發器

2.1 觸發器

觸發器是MySQL響應以下任意語句而自動執行的一條MySQL語句(或位於BEGIN和END語句之間的一組語句):DELETE、INSERT、UPDATE。

2.2 創建觸發器

在創建觸發器時,需要給出4條信息:

  • 唯一的觸發器名
  • 觸發器關聯的表
  • 觸發器應該響應的活動(DELETE、INSERT、UPDATE)
  • 觸發器何時執行(處理之前或之後)

觸發器用CREATE TRIGGER語句創建,示例如下:

CREATE TRIGGER newid AFTER INSERT ON table1 FOR EACH ROW SELECT 'id added';

CREATE TRIGGER用來創建名爲newid的新觸發器,觸發器可在一個操作發生之前或之後執行,
這裏是AFTER INSERT,所以此觸發器將在INSERT語句成功執行後執行。同時還指定了FOR EACH ROW,因此代碼對每個插入行執行。
操作結果如下:
TRIGGER
圖中出現錯誤:

Not allowed to return a result set from a trigger

表示觸發器不能執行SELECT返回結果,解決辦法用SELECT INTO來設置變量
修改後的命令如下:

CREATE TRIGGER newid AFTER INSERT ON table1 FOR EACH ROW SELECT 'id added' INTO @msg;

正確執行,然後查看變量的內容:

SELECT @msg;

上圖顯示結果爲NULL,接下來執行一條INSERT語句,然後再查看變量,顯示剛纔的’id added’字符。

2.3 刪除觸發器

刪除一個觸發器,可使用DROP TRIGGER語句,如下所示:

DROP TRIGGER newmsg;

2.4 使用觸發器

2.4.1 INSERT觸發器

INSERT觸發器在INSERT語句執行之前或之後執行,其要點如下:

  • 在INSERT觸發器代碼內,可引用一個名爲NEW的虛擬表,訪問被插入的行
  • 在BEFORE INSERT觸發器中,NEW中的值也可以被更新(允許更改被插入的值)
  • 對於AUTO_INCREMENT列,NEW在INSERT執行前包含0,在INSERT執行後包含新的自動生成值
    AUTO_INCREMENT列具有MySQL自動賦予的值,示例如下:
CREATE TRIGGER newtable AFTER INSERT ON table1 FOR EACH ROW SELECT NEW.quantity;

測試該觸發器:

INSERT INTO table1(name,id,quantity) VALUES('TN10',10,9);

結果如下:
INSERT trigger
和前面一樣也需要用SELECT INTO來設置變量

2.4.2 DELETE觸發器

DELETE觸發器在DELETE語句執行之前或之後執行,其要點如下:

  • 在DELETE觸發器代碼內,你可以引用一個名爲OLD的虛擬表,訪問被刪除的行
  • OLD中的值全都是隻讀的,不能更新
    使用OLD保存將要被刪除的行到一個存檔表中,示例如下:
CREATE TGIGGER deletetable BEFORE DELETE ON table1 FOR EACH ROW
BEGIN
    INSERT INTO del_orders(name,id,home)
    VALUES(OLD.name,OLD.id,OLD.home)
END;

使用BEFORE DELETE觸發器的優點(相對於AFTER DELETE觸發器來說)爲,如果由於某種原因,訂單不能存檔, DELETE本身將被放棄

2.4.3 UPDATE觸發器

UPDATE觸發器在UPDATE語句執行之前或之後執行,其要點如下:

  • 在UPDATE觸發器代碼中,可以引用一個名爲OLD的虛擬表訪問以前(UPDATE)的值,引用一個名爲NEW的虛擬表訪問新更新的值
  • 在BEFORE UPDATE觸發器中, NEW中的值可能也被更新(允許更改將要用於UPDATE語句中的值);
  • OLD中的值全部是隻讀的,不能更新
    以下示例保證home總是大寫(不管UPDATE語句中給出的是大寫還是小寫):
CREATE TRIGGER updatehome BEEFORE UPDATE ON table1 FOR EACH ROW SET NEW.home = Upper(NEW.home);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章