關系數據庫——視圖/存儲過程/觸發器

視圖

視圖是虛擬的表,與包含數據的表不同,視圖只包含使用時動態檢索數據的查詢,主要是用于查詢。

為什么使用視圖

  1. 重用sql語句
  2. 簡化復雜的sql操作,在編寫查詢后,可以方便地重用它而不必知道他的基本查詢細節。
  3. 使用表的組成部分而不是整個表。
  4. 保護數據。可以給用戶授予表的特定部分的訪問權限而不是整個表的訪問權限。
  5. 更改數據格式和表示。視圖可返回與底層表的表示和格式不同的數據。

注意:

  • 在視圖創建之后,可以用與表基本相同的方式利用它們。可以對視圖執行select操作,過濾和排序數據,將視圖聯結到其他視圖或表,甚至能添加和更新數據。
  • 重要的是知道視圖僅僅是用來查看存儲在別處的數據的一種設施。視圖本身不包含數據,因此它們返回的數據時從其他表中檢索出來的。在添加和更改這些表中的數據時,視圖將返回改變過的數據。
  • 因為視圖不包含數據,所以每次使用視圖時,都必須處理查詢執行時所需的任一檢索。如果你使用多個聯結和過濾創建了復雜的視圖或者嵌套了視圖,可能會發現性能下降得很厲害。因此,在部署使用了大量視圖的應用前,應該進行測試。

視圖的規則和限制

  1. 與表一樣,視圖必須唯一命名;
  2. 可以創建任意多的視圖;
  3. 為了創建視圖,必須具有足夠的訪問權限。這些限制通常由數據庫管理人員授予。
  4. 視圖可以嵌套,可以利用從其他視圖中檢索數據的查詢來構造一個視圖。
  5. Order by 可以在視圖中使用,但如果從該視圖檢索數據select中也是含有order by,那么該視圖的order by 將被覆蓋。
  6. 視圖不能索引,也不能有關聯的觸發器或默認值
  7. 視圖可以和表一起使用

視圖的創建

  1. 利用create view 語句來進行創建視圖
  2. 使用show create view viewname;來查看創建視圖的語句
  3. 用drop view viewname 來刪除視圖
  4. 更新視圖可以先drop在create,也可以使用create or replace view。

視圖的更新

視圖是否可以更新,要視情況而定。

通常情況下視圖是可以更新的,可以對他們進行insert,update和delete。更新視圖就是更新其基表(視圖本身沒有數據)。如果你對視圖進行增加或者刪除行,實際上就是對基表進行增加或者刪除行。

但是,如果MySQL不能正確的確定更新的基表數據,則不允許更新(包括插入和刪除),這就意味著視圖中如果存在以下操作則不能對視圖進行更新:(1)分組(使用group by 和 having );(2)聯結;(3)子查詢;(4)并;(5)聚集函數;(6)dictinct;(7)導出(計算)列。

?

存儲過程

存儲過程就是為了以后的使用而保存的一條或者多條MySQL語句的集合。可將視為批文件,雖然他們的作用不僅限于批處理。

為什么使用儲存過程?

1.通過把處理封裝在容易使用的單元中,簡化復雜的操作;

?

2.由于不要求反復建立一系列處理步驟,保證了數據的完整性。如果所有開發人員和應用程序都使用同一(實驗和測試)存儲過程,則所使用的代碼都是相同的。這一點的延伸就是防止錯誤。需要執行的步驟越多,出錯的可能性就越大,防止錯誤保證了數據的一致性。

?

3.簡化對變動的管理,如果表名。列名或者業務邏輯等有變化,只需要更改存儲過程的代碼。使用它的人員甚至不需要知道這些變化。這一點延伸就是安全性,通過存儲過程限制對基數據的訪問減少了數據訛誤的機會。

?

4.提高性能。因為使用存儲過程比使用單獨的sql語句更快。

?

5.存在一些只能用在單個請求的MySQL元素和特性,存儲過程可以使用他們來編寫功能更強更靈活的代碼

?

綜上:

三個主要的好處:簡單、安全、高性能。

兩個缺陷:

1、存儲過程的編寫更為復雜,需要更高的技能更豐富的經驗。

2、可能沒有創建存儲過程的安全訪問權限。許多數據庫管理員限制存儲過程的 創建權限,允許使用,不允許創建。

執行存儲過程

Call關鍵字:Call接受存儲過程的名字以及需要傳遞給他的任意參數。存儲過程可以顯示結果,也可以不顯示結果。

CREATE PROCEDURE productpricing()

??? BEGIN

??????? SELECT? AVG( prod_price)? as priceaverage FROM products;

??? END;

創建名為productpricing的儲存過程。如果存儲過程中需要傳遞參數,則將他們在括號中列舉出來即可。括號必須有。BEGIN和END關鍵字用來限制存儲過程體。上述存儲過程體本身是一個簡單的select語句。注意這里只是創建存儲過程并沒有進行調用。

?

儲存過程的使用:

?

Call productpring();

?

使用參數的存儲過程

一般存儲過程并不顯示結果,而是把結果返回給你指定的變量上。

變量:內存中一個特定的位置,用來臨時存儲數據。

MySQL> CREATE PROCEDURE prod(out pl decimal(8,2),out ph decimal(8,2),out pa decimal(8,2))
beginselect Min(prod_price) into pl from products;select MAx(prod_price) into ph from products;select avg(prod_price) into pa from products;end;call PROCEDURE(@pricelow,@pricehigh,@priceaverage);select @pricelow;select @pricehigh;select @pricelow,@pricehigh,@priceaverage;

?

解釋:

此存儲過程接受3個參數,pl存儲產品最低價,ph存儲產品最高價,pa存儲產品平均價。每個參數必須指定類型,使用的為十進制,關鍵字OUT 指出相應的參數用來從存儲過程傳出一個值(返回給調用者)。

?

MySQL支持in(傳遞給存儲過程)、out(從存儲過程傳出,這里所用)和inout(對存儲過程傳入和傳出)類型的參數。存儲過程的代碼位于begin和end語句內。他們是一系列select語句,用來檢索值。然后保存到相對應的變量(通過INTO關鍵字)。

存儲過程的參數允許的數據類型與表中使用的類型相同。注意記錄集是不被允許的類型,因此,不能通過一個參數返回多個行和列,這也是上面為什么要使用3個參數和3條select語句的原因。

?

調用:為調用此存儲過程,必須指定3個變量名。如上所示。3個參數是存儲過程保存結果的3個變量的名字。調用時,語句并不顯示任何數據,它返回以后可以顯示的變量(或在其他處理中使用)。

?

注意:所有的MySQL變量都是以@開頭。

CREATE PROCEDURE ordertotal(IN innumber int,OUT outtotal decimal(8,2))BEGINSELECT Sum(item_price * quantity) FROM orderitems WHERE order_num = innumber INTO outtotal;end??? //CALL ordertotal(20005,@total);select @total;? // 得到20005訂單的合計CALL ordertotal(20009,@total);select @total; //得到20009訂單的合計

?

帶有控制語句的存儲過程

??
CREATE PROCEDURE ordertotal(IN onumber INT,IN taxable BOOLEAN,OUT ototal DECIMAL(8,2))COMMENT 'Obtain order total, optionally adding tax'BEGIN-- declear variable for totalDECLARE total DECIMAL(8,2);-- declear tax percentageDECLARE taxrate INT DEFAULT 6;-- get the order totalSELECT Sum(item_price * quantity) FROM orderitems WHERE order_num = onumber INTO total;-- IS this taxable?IF taxable THEN-- yes ,so add taxrate to the totalSELECT total+(total/100*taxrate)INTO total;END IF;-- finally ,save to out variableSELECT total INTO ototal;END;

在存儲過程中我們使用了DECLARE語句,他們表示定義兩個局部變量,DECLARE要求指定變量名和數據類型。它也支持可選的默認值(taxrate默認6%),因為后期我們還要判斷要不要增加稅,所以,我們把SELECT查詢的結果存儲到局部變量total中,然后在IF 和THEN的配合下,檢查taxable是否為真,然后在真的情況下,我們利用另一條SELECT語句增加營業稅到局部變量total中,然后我們再利用SELECT語句將total(增加稅或者不增加稅的結果)保存到總的ototal中。

COMMENT關鍵字 上面的COMMENT是可以給出或者不給出,如果給出,將在SHOW PROCEDURE STATUS的結果中顯示。

?

觸發器

在某個表發生更改時自動處理某些語句,這就是觸發器。

?

觸發器是MySQL響應delete 、update 、insert 、位于begin 和end語句之間的一組語句而自動執行的一條MySQL語句。其他的語句不支持觸發器。

創建觸發器

在創建觸發器時,需要給出4條語句(規則):

1.? 唯一的觸發器名;

2.? 觸發器關聯的表;

3.? 觸發器應該響應的活動;

4.? 觸發器何時執行(處理之前或者之后)

?

Create trigger 語句創建 觸發器

CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT 'Product added' INTO @info;

CREATE TRIGGER用來創建名為newproduct的新觸發器。觸發器可以在一個操作發生前或者發生后執行,這里AFTER INSERT 是指此觸發器在INSERT語句成功執行后執行。這個觸發器還指定FOR EACH ROW , 因此代碼對每個插入行都會執行。文本Product added 將對每個插入的行顯示一次。

?

注意:

1、觸發器只有表才支持,視圖,臨時表都不支持觸發器。

2、觸發器是按照每個表每個事件每次地定義,每個表每個事件每次只允許一個觸發器,因此,每個表最多支持六個觸發器(insert,update,delete的before 和after)。

3、單一觸發器不能與多個事件或多個表關聯,所以,你需要一個對insert和update 操作執行的觸發器,則應該定義兩個觸發器。

4、觸發器失敗:如果before 觸發器失敗,則MySQL將不執行請求的操作,此外,如果before觸發器或者語句本身失敗,MySQL則將不執行after觸發器。

觸發器類別

INSERT觸發器

是在insert語句執行之前或者執行之后被執行的觸發器。

1、在insert觸發器代碼中,可引入一個名為new的虛擬表,訪問被插入的行;

2、在before insert觸發器中,new中的值也可以被更新(允許更改被插入的值);

3、對于auto_increment列,new在insert執行之前包含0,在insert執行之后包含新的自動生成值

CREATE TRIGGER neworder AFTER INSERT ON orders FOR EACH ROW SELECT NEW.order_num;

創建一個名為neworder的觸發器,按照AFTER INSERT ON orders 執行。在插入一個新訂單到orders表時,MySQL生成一個新的訂單號并保存到order_num中。觸發器從NEW.order_num取得這個值并返回它。此觸發器必須按照AFTER INSERT執行,因為在BEFORE INSERT語句執行之前,新order_num還沒有生成。對于orders的每次插入使用這個觸發器總是返回新的訂單號。

DELETE觸發器

Delete觸發器在delete語句執行之前或者之后執行。

1、在delete觸發器的代碼內,可以引用一個名為OLD的虛擬表,用來訪問被刪除的行。

2、OLD中的值全為只讀,不能更新。

CREATE TRIGGER deleteorder BEFORE DELETE ON orders FOR EACH ROWBEGININSERT INTO archive_orders(order_num,order_date,cust_id) values (OLD.order_num,OLD.order_date,OLD.cust_id);END;----------------------------------------------------------------CREATE TABLE archive_orders(order_num int(11) NOT NULL AUTO_INCREMENT,order_date datetime NOT NULL,cust_id int(11) NOT NULL,PRIMARY KEY (order_num),KEY fk_orders1_customers1 (cust_id),CONSTRAINT fk_orders1_customers1 FOREIGN KEY (cust_id) REFERENCES customers(cust_id)) ENGINE=InnoDB AUTO_INCREMENT=20011 DEFAULT CHARSET=utf8

在任意訂單被刪除前將執行此觸發器,它使用一條INSERT 語句將OLD中的值(要被刪除的訂單) 保存到一個名為archive_orders的存檔表中(為實際使用這個例子,我們需要用與orders相同的列創建一個名為archive_orders的表)

?

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

?

我們在這個觸發器使用了BEGIN和END語句標記觸發器體。這在此例子中并不是必須的,只是為了說明使用BEGIN END 塊的好處是觸發器能夠容納多條SQL 語句(在BEGIN END塊中一條挨著一條)。

UPDATE觸發器

在update語句執行之前或者之后執行

1、在update觸發器的代碼內,可以引用一個名為OLD的虛擬表,用來訪問以前(UPDATE語句之前)的值,引用一個名為NEW的虛擬表訪問新更新的值。

2、在BEFORE UPDATE觸發器中,NEW中的值可能也被用于更新(允許更改將要用于UPDATE語句中的值)

3、OLD中的值全為只讀,不能更新。

CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors FOR EACH ROW SET NEW.vend_state = Upper(NEW.vemd_state);

保證州名縮寫總是大寫(不管UPFATE語句中是否給出了大寫),每次更新一行時,NEW.vend_state中的值(將用來更新表行的值)都用Upper(NEW.vend_state)替換。

總結

1、通常before用于數據的驗證和凈化(為了保證插入表中的數據確實是需要的數據) 也適用于update觸發器。

2、與其他DBMS相比,MySQL 5中支持的觸發器相當初級,未來的MySQL版本中估計會存在一些改進和增強觸發器的支持。

3、創建觸發器可能需要特殊的安全訪問權限,但是觸發器的執行時自動的,如果insert,update,或者delete語句能夠執行,則相關的觸發器也能執行。

4、用觸發器來保證數據的一致性(大小寫,格式等)。在觸發器中執行這種類型的處理的優點就是它總是進行這種處理,而且透明的進行,與客戶機應用無關。

5、觸發器的一種非常有意義的使用就是創建審計跟蹤。使用觸發器,把更改(如果需要,甚至還有之前和之后的狀態)記錄到另外一個表是非常容易的。

6、MySQL觸發器不支持call語句,無法從觸發器內調用存儲過程。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/444886.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/444886.shtml
英文地址,請注明出處:http://en.pswp.cn/news/444886.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++(5)--運算符、表達式、條件結構(if, switch)

C運算符、表達式 條件結構1.表達式與運算符1.1賦值運算符1.2算術運算符1.3關系運算符1.4邏輯運算符1.5位運算符1.6 sizeof()1.7 三目運算符1.8 運算符的優先級2.條件結構2.1--if2.2 --switch結構2.3 switch 和 多重if 結構的對比條件結構)《老九學堂C課程》《C primer》學習筆記…

關系數據庫——mysql常用函數總結

文本處理函數 Left(x,len) – 返回串左邊的字符(長度為len) Right(x,len) Length(x) – 返回串的長度 Locate(x,sub_x) – 找出串的一個子串 SubString(x, from, to) – 返回字串的字符 Lower(x) Upper(x) LTrim(x) RTrim(x) Soundex(x) – 讀…

setsockopt()用法(參數詳細說明)

先來看看函數的原型: int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); 然后我們來看看參數: s(套接字): 指向一個打開的套接口描述字 level:(級別): 指定選項代碼的類型。

再議libcurl編程

那是2年前用libcurl了,我肯定好久不用的知識,放置久了就會遺忘,現在我又重拾起這個知識點,重頭再來,至于前面的基礎知識,可以參考我的 http://blog.csdn.net/pbymw8iwm/article/details/6675754 假設你要獲取URL所表示的遠程主機上的資源。你需要寫一段程序用來完…

關系數據庫——并發控制

并發控制 多用戶數據庫:允許多個用戶同時使用的數據庫(訂票系統) 不同的多事務執行方式: 1.串行執行:每個時刻只有一個事務運行,其他事務必須等到這個事務結束后方能運行。 2.交叉并發方式: …

C++(6)--初識循環while,do-while

初識循環1.使用while 循環結構2.使用do-while 循環3.python中的while循環《老九學堂C課程》《C primer》學習筆記。《老九學堂C課程》詳情請到B站搜索《老九零基礎學編程C入門》-------------簡單的事情重復做,重復的事情用心做,用心的事情堅持做(老九君…

map類的erase方法的在Linux與Windows中的差異

這次的代碼是跨平臺的,尼瑪在win32上通過,但是在linux上不通過了,查找了一下原來是平臺linux不支持。 有人舉了例子: std::map< int , float > i_f_map; i_f_map[1] = 1.2f; i_f_map[23] = 1.4f;

C++(7)--for循環,break,continue語句

for循環1.for循環2.break 語句3.continue語句4.while,do-while,for 循環的異同5.for循環demo 嵌套循環-打印圖形6.python 中的for循環《老九學堂C課程》《C primer》學習筆記。《老九學堂C課程》詳情請到B站搜索《老九零基礎學編程C入門》-------------簡單的事情重復做&#x…

關系數據庫——數據庫恢復

實現技術 恢復操作的基本原理&#xff1a;冗余 恢復機制涉及的兩個關鍵問題 如何建立冗余數據 數據轉儲&#xff08;backup&#xff09;登錄日志文件&#xff08;logging&#xff09; 如何利用這些冗余數據實施數據庫恢復數據轉儲 數據轉儲定義&#xff1a; 轉儲是指DBA將整個數…

Lua語言中pairs和ipairs的區別

tbl = {"alpha", "beta", ["one"] = "uno", ["two"] = "dos"} for key, value in ipairs(tbl) do print(key, value) end --pairs() --pairs()函數基本和ipairs()函數用法相同, 區別在于pairs()可以遍歷整個table…

算法(22)-leetcode-劍指offer6

leetcode-劍指offer-545.面試題55- 二叉樹的深度46.面試題55-2-平衡二叉樹47.面試題57-1-和為s的兩個數字-雙指針48.面試題57-2-和為s 的連續正數序列-雙指針49.面試題56-數組中出現數字的次數-位運算leetcode-136 只出現一次的數字Ileetcode-137 只出現一次的數字IIleetcode-2…

leetcode160 相交鏈表

編寫一個程序&#xff0c;找到兩個單鏈表相交的起始節點。 如下面的兩個鏈表&#xff1a; 在節點 c1 開始相交。 示例 1&#xff1a; 輸入&#xff1a;intersectVal 8, listA [4,1,8,4,5], listB [5,0,1,8,4,5], skipA 2, skipB 3 輸出&#xff1a;Reference of the node…

lua的一些api文檔總結吧

打算記錄一些我認為重要的常用的api: 1. 建一個新表 void lua_createtable (lua_State *L, int narr, int nrec) 創建一個新的table, 并把它放在棧頂. narr和nrec分別指定該table的array部分和hash部分的預分配元素數量 無返回值 棧高度+1, 棧頂元素是新table #define l…

關于mysql的一些時間格式和字符的問題

最近在做一些游戲的數據分析&#xff0c;需要對大量數據的用戶行為進行處理存庫&#xff0c;其中有個數據庫字段是datetime類型的&#xff0c;這個以前都沒用過&#xff0c;我以前都喜歡用int來存放時間戳&#xff0c;但這次這樣用&#xff0c;我就得在數據庫中轉換了&#xff…

算法(17)-leetcode-劍指offer1

leetcode-劍指offer-11.面試題3-數組中的重復數字2.面試題04-二維數組中的查找3.面試題05-替換空格4.面試題06-從尾到頭打印鏈表5.面試題07-重建二叉樹6.面試題09-兩個堆棧實現隊列7.面試題10-1-斐波那契數列8.面試題10-2-青蛙跳臺階問題9.面試題11-旋轉數組的最小數字10.面試題…

蟻群算法的一些東西

運行了三個TSP經典用例,基本符合要求。僅僅是一份按照蟻群算法的原理寫的代碼,沒有做任何優化。 // bigSearch.cpp : 定義控制臺應用程序的入口點。 // #include<iostream> #include<math.h> #include<time.h> using namespace std; //該程序是以…

leetcode101 對稱二叉樹

給定一個二叉樹&#xff0c;檢查它是否是鏡像對稱的。 例如&#xff0c;二叉樹 [1,2,2,3,4,4,3] 是對稱的。 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面這個 [1,2,2,null,3,null,3] 則不是鏡像對稱的: 1 / \ 2 2 \ \ 3 3 說明: 如果你可以運用遞歸和迭…

Linux內核OOM機制的詳細分析

Linux 內核有個機制叫OOM killer&#xff08;Out-Of-Memory killer&#xff09;&#xff0c;該機制會監控那些占用內存過大&#xff0c;尤其是瞬間很快消耗大量內存的進程&#xff0c;為了防止內存耗盡而內核會把該進程殺掉。典型的情況是&#xff1a;某天一臺機器突然ssh遠程登…

算法(18)-leetcode-劍指offer2

leetcode-劍指offer-211.面試題13-機器人的運動范圍-廣度優先搜索12.面試題14-1-剪繩子13.面試題14-2-剪繩子214.面試題16-二進制中1的個數-布萊恩克尼根15.面試題16-數值的整數次方-快速冪解析法16.面試題17-打印從1到最大的n位數17.面試題18-刪除鏈表的節點18.面試題19-正則匹…

rabbitmq技術的一些感悟(一)

Rabbitmq 初識rabbitmq RabbitMQ是流行的開源消息隊列系統,用erlang語言開發。RabbitMQ是AMQP(高級消息隊列協議)的標準實現。如果不熟悉AMQP,直接看RabbitMQ的文檔會比較困難。不過它也只有幾個關鍵概念,這里簡單介紹 幾個概念說明: Broker