定義:是一個存儲在MySQL服務器上的數據庫查詢,是一種被select語句檢索出來的結果集。sql
做用:方便在檢索出來的結果集中前進或後退一行或多行。數據庫
PS:遊標主要用於交互式應用;MySQL中的遊標只能用於存儲過程(和函數)。安全
1、建立遊標服務器
遊標使用declare語句建立;declare命名遊標,並定義相應的select語句,根據須要帶where和其餘子句;例如:函數
create procedure processorders() begin declare ordernumbers CURSOR for select order_num from orders; end;
這個存儲過程當中,declare定義和命名了遊標ordernumbers,存儲過程處理完成後,遊標就消失(侷限於存儲過程內)。oop
2、打開和關閉遊標fetch
定義遊標以後,能夠打開它,用open cursor語句來打開,例如:open ordernumbers;spa
在處理open語句時執行查詢,存儲檢索出的數據以供瀏覽和滾動;指針
遊標處理完成時,用close語句關閉,例如:close ordernumbers;code
close釋放遊標使用的全部內部內存和資源,所以在每一個遊標不在須要時都應該關閉。
PS:
遊標關閉後,若是沒有從新打開,則不能使用;但若是該遊標被聲明過,則不須要再次聲明,用open打開使用便可。
若是不明確遊標是否關閉,MySQL將會在到達end語句時自動關閉該遊標。
3、使用遊標數據
遊標被打開後,使用fetch語句分別訪問它的每一行;fetch指定檢索什麼數據(所需的列),檢索的數據存儲在什麼地方,還向前移動遊標中的內部行指針,使下一條fetch語句檢索下一行(不重複讀取)。
檢索第一行數據,例如:
create procedure processorders() begin --declare local variables declare o int; --declare the cursor declare ordernumbers cursor for select order_num from orders; --open the cursor open ordernumbers; --get order number fetch ordernumbers into o; --close the cursor close ordernumbers; end;
這條語句中fetch用來檢索當前行的order_num列(自動從第一行開始)到一個名爲o的局部聲明變量中;對檢索出的數據不作任何處理。
循環檢索數據,從第一行到最後一行,以下:
create procedure processorders() --建立存儲過程 begin --declare local variables declare done boolean default 0; declare 0 int; --declare the cursor declare ordernumbers cursor for select order_num from orders; --結果集 --declare continue handler declare continue handler for sqlstate '02000' set done=1; --在這裏,done被設置爲結束時爲真 --open the cursor open ordernumbers; --loop through all rows repeat --get order number fetch ordernumbers into o; --end of loop until done end repeat; --close the cursor close ordernumbers; end;
與前一個例子同樣,用fetch檢索當前order_num到聲明的o變量中。區別在於:這個例子中fetch是在repeat內,所以它反覆執行到done爲真(由until done end repeat;規定)。
在語句(declare continue handler for sqlstate '02000' set done=1;)中,定義了CONTINUE HANDLER,它是在條件出現時被執行的代碼。當SQLSTATE '02000'出現時,SET done=1。
SQLSTATE '02000'是一個未找到條件,當REPEAT因爲沒有更多的行供循環而不能繼續時,出現這個條件。done被設置爲真。
PS:
用declare語句定義的局部變量必須在定義任意遊標或句柄以前定義,而句柄必須在遊標以後定義。
MySQL還支持循環語句,它可用來重複執行代碼,直到使用leave語句手動退出爲止;一般repeat語句的語法使它更適合於對遊標進行循環。
4、使用遊標的幾個注意事項
一、在使用遊標前,必須聲明(定義)它;這個過程實際沒有檢索數據,只是定義要使用的select語句;
二、一旦聲明,則必須打開遊標以供使用(這個過程用前面定義的select語句把數據實際檢索出來);
三、對於填有數據的遊標,根據須要取出(檢索)各行;
四、結束遊標使用時,必須關閉遊標。
MySQL語句在須要時被執行,存儲過程也是如此,若是但願某條語句(或某些語句)在事件發生時自動執行,這就須要用到觸發器。
觸發器是MySQL響應如下任意語句而自動執行的一條MySQL語句(或位於begin和end語句之間的一組語句):delete;insert;update。其餘MySQL語句不支持觸發器。
1、建立觸發器
須要的信息:惟一的觸發器名;觸發器關聯的表;觸發器應該響應的活動(delete、insert或update);觸發器什麼時候執行(處理以前或以後)。
PS:MySQL中,觸發器名必須在每一個表中惟一,但不是在每一個數據庫中惟一。即:同一數據庫中兩個表能夠具備相同名字的觸發器,但其餘的DBMS中不被容許,因此最好是在數據庫範圍內使用惟一的觸發器名。
觸發器使用create teigger語句建立,如:
create trigger newproduct after insert on products for each row select 'product added';
建立newproduct觸發器,給出了after insert,因此此觸發器在insert語句成功執行後執行;還指定了for each row,所以代碼對每一個插入行執行。
PS:
一、只有表才支持觸發器,視圖不支持(臨時表也不支持)。
二、觸發器按每一個表每一個事件每次的定義,每一個表每一個事件每次只容許一個觸發器;所以每一個表最多支持6個觸發器(每條insert、update和delete的以前和以後),單一觸發器不能與多個事件或多個表關聯。
三、若是before觸發器失敗,則MySQL將不執行請求的操做;此外,若是before觸發器或語句自己失敗,MySQL將不執行after觸發器(若是有的話)。
2、刪除觸發器
刪除觸發器用drop trigger語句,如:
drop trigger newproduct;
PS:觸發器不能更新或覆蓋;爲了修改一個觸發器,必須先刪再建。
3、使用觸發器
1、insert觸發器
使用insert觸發器,須要知道如下三點:
一、在insert觸發器代碼內,可引用一個名爲new的虛擬表,訪問被插入的行;
二、在before insert觸發器內,new中的值也能夠被更新(容許更改被插入的值);
三、對於auto increment列,new在insert執行以前包含0,在insert執行以後包含新的自動生成值;
對於AUTO_INCREMENT自動賦予的值,肯定新生成值的方法,例子以下:
create trigger neworder after insert on orders for each row select new.order_num;
建立一個名爲neworder的觸發器,按照after insert on order執行;在插入一條新的數據到orders表時,MySQL生成一個新訂單號並保存到order_num中;
觸發器從new.order_num取這個值並返回它;此觸發器必須按照after insert執行,由於在before insert語句執行以前,新order_num還沒生成。
PS:一般將before用於數據驗證和淨化(目的是保證插入表中的數據確實是須要的數據)。這個規則也適用於update觸發器。
2、delete觸發器
使用delete觸發器,須要知道如下兩點:
一、在delete觸發器代碼內,能夠引用一個名爲old的虛擬表,訪問被刪除的行;
二、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;
在任意數據被刪除前執行此觸發器;它使用insert語句將old中的值(要被刪除的數據)保存到一個名爲archive_orders的存檔表中;
PS:使用begin end塊的好處是觸發器能容納多條SQL語句。
3、update觸發器
使用update觸發器,須要知道如下三點:
一、在update觸發器代碼內,能夠引用一個名爲old的虛擬表訪問之前(update語句前)的值,引用一個名爲new的虛擬表訪問新更新的值;
二、在before update觸發器中,new中的值可能也被更新(容許更改將要用於update語句中的值);
三、old中的值全都是隻讀的,不能更新;
下面的例子,保證了州名稱縮寫老是大寫:
create trigger updateevendor before update on vendors for each row set new.vend_state = upper(new.vend_state);
每次更新一個行時,new.vend_state中的值都用upper(new.vend_state)替換。
4、關於觸發器一些必須知道的知識:
一、建立觸發器可能須要特殊的安全訪問權限,但觸發器的執行是自動的。若是insert、update或delete語句能夠執行,則相應觸發器也能執行;
二、應該用觸發器來保證數據的一致性(大小寫、格式等);優勢在於它老是進行這種處理,並且是透明的進行,與客戶機應用無關;
三、觸發器的一種很是有意義的使用是建立審計跟蹤。使用觸發器,把更改記錄到另外一個表很是容易;
四、MySQL觸發器不支持call語句,即不能從觸發器內調用存儲過程。所需的存儲過程代碼須要複製到觸發器內。