日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

关系数据库——视图/存储过程/触发器

發(fā)布時(shí)間:2023/12/13 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关系数据库——视图/存储过程/触发器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

視圖

視圖是虛擬的表,與包含數(shù)據(jù)的表不同,視圖只包含使用時(shí)動(dòng)態(tài)檢索數(shù)據(jù)的查詢(xún),主要是用于查詢(xún)。

為什么使用視圖

  • 重用sql語(yǔ)句
  • 簡(jiǎn)化復(fù)雜的sql操作,在編寫(xiě)查詢(xún)后,可以方便地重用它而不必知道他的基本查詢(xún)細(xì)節(jié)。
  • 使用表的組成部分而不是整個(gè)表。
  • 保護(hù)數(shù)據(jù)??梢越o用戶(hù)授予表的特定部分的訪(fǎng)問(wèn)權(quán)限而不是整個(gè)表的訪(fǎng)問(wèn)權(quán)限。
  • 更改數(shù)據(jù)格式和表示。視圖可返回與底層表的表示和格式不同的數(shù)據(jù)。
  • 注意:

    • 在視圖創(chuàng)建之后,可以用與表基本相同的方式利用它們??梢詫?duì)視圖執(zhí)行select操作,過(guò)濾和排序數(shù)據(jù),將視圖聯(lián)結(jié)到其他視圖或表,甚至能添加和更新數(shù)據(jù)。
    • 重要的是知道視圖僅僅是用來(lái)查看存儲(chǔ)在別處的數(shù)據(jù)的一種設(shè)施。視圖本身不包含數(shù)據(jù),因此它們返回的數(shù)據(jù)時(shí)從其他表中檢索出來(lái)的。在添加和更改這些表中的數(shù)據(jù)時(shí),視圖將返回改變過(guò)的數(shù)據(jù)。
    • 因?yàn)橐晥D不包含數(shù)據(jù),所以每次使用視圖時(shí),都必須處理查詢(xún)執(zhí)行時(shí)所需的任一檢索。如果你使用多個(gè)聯(lián)結(jié)和過(guò)濾創(chuàng)建了復(fù)雜的視圖或者嵌套了視圖,可能會(huì)發(fā)現(xiàn)性能下降得很厲害。因此,在部署使用了大量視圖的應(yīng)用前,應(yīng)該進(jìn)行測(cè)試。

    視圖的規(guī)則和限制

  • 與表一樣,視圖必須唯一命名;
  • 可以創(chuàng)建任意多的視圖;
  • 為了創(chuàng)建視圖,必須具有足夠的訪(fǎng)問(wèn)權(quán)限。這些限制通常由數(shù)據(jù)庫(kù)管理人員授予。
  • 視圖可以嵌套,可以利用從其他視圖中檢索數(shù)據(jù)的查詢(xún)來(lái)構(gòu)造一個(gè)視圖。
  • Order by 可以在視圖中使用,但如果從該視圖檢索數(shù)據(jù)select中也是含有order by,那么該視圖的order by 將被覆蓋。
  • 視圖不能索引,也不能有關(guān)聯(lián)的觸發(fā)器或默認(rèn)值
  • 視圖可以和表一起使用
  • 視圖的創(chuàng)建

  • 利用create view 語(yǔ)句來(lái)進(jìn)行創(chuàng)建視圖
  • 使用show create view viewname;來(lái)查看創(chuàng)建視圖的語(yǔ)句
  • 用drop view viewname 來(lái)刪除視圖
  • 更新視圖可以先drop在create,也可以使用create or replace view。
  • 視圖的更新

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

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

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

    ?

    存儲(chǔ)過(guò)程

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

    為什么使用儲(chǔ)存過(guò)程?

    1.通過(guò)把處理封裝在容易使用的單元中,簡(jiǎn)化復(fù)雜的操作;

    ?

    2.由于不要求反復(fù)建立一系列處理步驟,保證了數(shù)據(jù)的完整性。如果所有開(kāi)發(fā)人員和應(yīng)用程序都使用同一(實(shí)驗(yàn)和測(cè)試)存儲(chǔ)過(guò)程,則所使用的代碼都是相同的。這一點(diǎn)的延伸就是防止錯(cuò)誤。需要執(zhí)行的步驟越多,出錯(cuò)的可能性就越大,防止錯(cuò)誤保證了數(shù)據(jù)的一致性。

    ?

    3.簡(jiǎn)化對(duì)變動(dòng)的管理,如果表名。列名或者業(yè)務(wù)邏輯等有變化,只需要更改存儲(chǔ)過(guò)程的代碼。使用它的人員甚至不需要知道這些變化。這一點(diǎn)延伸就是安全性,通過(guò)存儲(chǔ)過(guò)程限制對(duì)基數(shù)據(jù)的訪(fǎng)問(wèn)減少了數(shù)據(jù)訛誤的機(jī)會(huì)。

    ?

    4.提高性能。因?yàn)槭褂么鎯?chǔ)過(guò)程比使用單獨(dú)的sql語(yǔ)句更快。

    ?

    5.存在一些只能用在單個(gè)請(qǐng)求的MySQL元素和特性,存儲(chǔ)過(guò)程可以使用他們來(lái)編寫(xiě)功能更強(qiáng)更靈活的代碼

    ?

    綜上:

    三個(gè)主要的好處:簡(jiǎn)單、安全、高性能。

    兩個(gè)缺陷:

    1、存儲(chǔ)過(guò)程的編寫(xiě)更為復(fù)雜,需要更高的技能更豐富的經(jīng)驗(yàn)。

    2、可能沒(méi)有創(chuàng)建存儲(chǔ)過(guò)程的安全訪(fǎng)問(wèn)權(quán)限。許多數(shù)據(jù)庫(kù)管理員限制存儲(chǔ)過(guò)程的 創(chuàng)建權(quán)限,允許使用,不允許創(chuàng)建。

    執(zhí)行存儲(chǔ)過(guò)程

    Call關(guān)鍵字:Call接受存儲(chǔ)過(guò)程的名字以及需要傳遞給他的任意參數(shù)。存儲(chǔ)過(guò)程可以顯示結(jié)果,也可以不顯示結(jié)果。

    CREATE PROCEDURE productpricing()

    ??? BEGIN

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

    ??? END;

    創(chuàng)建名為productpricing的儲(chǔ)存過(guò)程。如果存儲(chǔ)過(guò)程中需要傳遞參數(shù),則將他們?cè)诶ㄌ?hào)中列舉出來(lái)即可。括號(hào)必須有。BEGIN和END關(guān)鍵字用來(lái)限制存儲(chǔ)過(guò)程體。上述存儲(chǔ)過(guò)程體本身是一個(gè)簡(jiǎn)單的select語(yǔ)句。注意這里只是創(chuàng)建存儲(chǔ)過(guò)程并沒(méi)有進(jìn)行調(diào)用。

    ?

    儲(chǔ)存過(guò)程的使用:

    ?

    Call productpring();

    ?

    使用參數(shù)的存儲(chǔ)過(guò)程

    一般存儲(chǔ)過(guò)程并不顯示結(jié)果,而是把結(jié)果返回給你指定的變量上。

    變量:內(nèi)存中一個(gè)特定的位置,用來(lái)臨時(shí)存儲(chǔ)數(shù)據(jù)。

    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;

    ?

    解釋:

    此存儲(chǔ)過(guò)程接受3個(gè)參數(shù),pl存儲(chǔ)產(chǎn)品最低價(jià),ph存儲(chǔ)產(chǎn)品最高價(jià),pa存儲(chǔ)產(chǎn)品平均價(jià)。每個(gè)參數(shù)必須指定類(lèi)型,使用的為十進(jìn)制,關(guān)鍵字OUT 指出相應(yīng)的參數(shù)用來(lái)從存儲(chǔ)過(guò)程傳出一個(gè)值(返回給調(diào)用者)。

    ?

    MySQL支持in(傳遞給存儲(chǔ)過(guò)程)、out(從存儲(chǔ)過(guò)程傳出,這里所用)和inout(對(duì)存儲(chǔ)過(guò)程傳入和傳出)類(lèi)型的參數(shù)。存儲(chǔ)過(guò)程的代碼位于begin和end語(yǔ)句內(nèi)。他們是一系列select語(yǔ)句,用來(lái)檢索值。然后保存到相對(duì)應(yīng)的變量(通過(guò)INTO關(guān)鍵字)。

    存儲(chǔ)過(guò)程的參數(shù)允許的數(shù)據(jù)類(lèi)型與表中使用的類(lèi)型相同。注意記錄集是不被允許的類(lèi)型,因此,不能通過(guò)一個(gè)參數(shù)返回多個(gè)行和列,這也是上面為什么要使用3個(gè)參數(shù)和3條select語(yǔ)句的原因。

    ?

    調(diào)用:為調(diào)用此存儲(chǔ)過(guò)程,必須指定3個(gè)變量名。如上所示。3個(gè)參數(shù)是存儲(chǔ)過(guò)程保存結(jié)果的3個(gè)變量的名字。調(diào)用時(shí),語(yǔ)句并不顯示任何數(shù)據(jù),它返回以后可以顯示的變量(或在其他處理中使用)。

    ?

    注意:所有的MySQL變量都是以@開(kāi)頭。

    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訂單的合計(jì)CALL ordertotal(20009,@total);select @total; //得到20009訂單的合計(jì)

    ?

    帶有控制語(yǔ)句的存儲(chǔ)過(guò)程

    ?? 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;

    在存儲(chǔ)過(guò)程中我們使用了DECLARE語(yǔ)句,他們表示定義兩個(gè)局部變量,DECLARE要求指定變量名和數(shù)據(jù)類(lèi)型。它也支持可選的默認(rèn)值(taxrate默認(rèn)6%),因?yàn)楹笃谖覀冞€要判斷要不要增加稅,所以,我們把SELECT查詢(xún)的結(jié)果存儲(chǔ)到局部變量total中,然后在IF 和THEN的配合下,檢查taxable是否為真,然后在真的情況下,我們利用另一條SELECT語(yǔ)句增加營(yíng)業(yè)稅到局部變量total中,然后我們?cè)倮肧ELECT語(yǔ)句將total(增加稅或者不增加稅的結(jié)果)保存到總的ototal中。

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

    ?

    觸發(fā)器

    在某個(gè)表發(fā)生更改時(shí)自動(dòng)處理某些語(yǔ)句,這就是觸發(fā)器。

    ?

    觸發(fā)器是MySQL響應(yīng)delete 、update 、insert 、位于begin 和end語(yǔ)句之間的一組語(yǔ)句而自動(dòng)執(zhí)行的一條MySQL語(yǔ)句。其他的語(yǔ)句不支持觸發(fā)器。

    創(chuàng)建觸發(fā)器

    在創(chuàng)建觸發(fā)器時(shí),需要給出4條語(yǔ)句(規(guī)則):

    1.? 唯一的觸發(fā)器名;

    2.? 觸發(fā)器關(guān)聯(lián)的表;

    3.? 觸發(fā)器應(yīng)該響應(yīng)的活動(dòng);

    4.? 觸發(fā)器何時(shí)執(zhí)行(處理之前或者之后)

    ?

    Create trigger 語(yǔ)句創(chuàng)建 觸發(fā)器

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

    CREATE TRIGGER用來(lái)創(chuàng)建名為newproduct的新觸發(fā)器。觸發(fā)器可以在一個(gè)操作發(fā)生前或者發(fā)生后執(zhí)行,這里AFTER INSERT 是指此觸發(fā)器在INSERT語(yǔ)句成功執(zhí)行后執(zhí)行。這個(gè)觸發(fā)器還指定FOR EACH ROW , 因此代碼對(duì)每個(gè)插入行都會(huì)執(zhí)行。文本Product added 將對(duì)每個(gè)插入的行顯示一次。

    ?

    注意:

    1、觸發(fā)器只有表才支持,視圖,臨時(shí)表都不支持觸發(fā)器。

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

    3、單一觸發(fā)器不能與多個(gè)事件或多個(gè)表關(guān)聯(lián),所以,你需要一個(gè)對(duì)insert和update 操作執(zhí)行的觸發(fā)器,則應(yīng)該定義兩個(gè)觸發(fā)器。

    4、觸發(fā)器失敗:如果before 觸發(fā)器失敗,則MySQL將不執(zhí)行請(qǐng)求的操作,此外,如果before觸發(fā)器或者語(yǔ)句本身失敗,MySQL則將不執(zhí)行after觸發(fā)器。

    觸發(fā)器類(lèi)別

    INSERT觸發(fā)器

    是在insert語(yǔ)句執(zhí)行之前或者執(zhí)行之后被執(zhí)行的觸發(fā)器。

    1、在insert觸發(fā)器代碼中,可引入一個(gè)名為new的虛擬表,訪(fǎng)問(wèn)被插入的行;

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

    3、對(duì)于auto_increment列,new在insert執(zhí)行之前包含0,在insert執(zhí)行之后包含新的自動(dòng)生成值

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

    創(chuàng)建一個(gè)名為neworder的觸發(fā)器,按照AFTER INSERT ON orders 執(zhí)行。在插入一個(gè)新訂單到orders表時(shí),MySQL生成一個(gè)新的訂單號(hào)并保存到order_num中。觸發(fā)器從NEW.order_num取得這個(gè)值并返回它。此觸發(fā)器必須按照AFTER INSERT執(zhí)行,因?yàn)樵贐EFORE INSERT語(yǔ)句執(zhí)行之前,新order_num還沒(méi)有生成。對(duì)于orders的每次插入使用這個(gè)觸發(fā)器總是返回新的訂單號(hào)。

    DELETE觸發(fā)器

    Delete觸發(fā)器在delete語(yǔ)句執(zhí)行之前或者之后執(zhí)行。

    1、在delete觸發(fā)器的代碼內(nèi),可以引用一個(gè)名為OLD的虛擬表,用來(lái)訪(fǎng)問(wèn)被刪除的行。

    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

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

    ?

    使用BEFORE DELETE觸發(fā)器的優(yōu)點(diǎn)(相對(duì)于AFTER DELETE觸發(fā)器來(lái)說(shuō))為,如果由于某種原因,訂單不能存檔,delete本身將被放棄。

    ?

    我們?cè)谶@個(gè)觸發(fā)器使用了BEGIN和END語(yǔ)句標(biāo)記觸發(fā)器體。這在此例子中并不是必須的,只是為了說(shuō)明使用BEGIN END 塊的好處是觸發(fā)器能夠容納多條SQL 語(yǔ)句(在BEGIN END塊中一條挨著一條)。

    UPDATE觸發(fā)器

    在update語(yǔ)句執(zhí)行之前或者之后執(zhí)行

    1、在update觸發(fā)器的代碼內(nèi),可以引用一個(gè)名為OLD的虛擬表,用來(lái)訪(fǎng)問(wèn)以前(UPDATE語(yǔ)句之前)的值,引用一個(gè)名為NEW的虛擬表訪(fǎng)問(wèn)新更新的值。

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

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

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

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

    總結(jié)

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

    2、與其他DBMS相比,MySQL 5中支持的觸發(fā)器相當(dāng)初級(jí),未來(lái)的MySQL版本中估計(jì)會(huì)存在一些改進(jìn)和增強(qiáng)觸發(fā)器的支持。

    3、創(chuàng)建觸發(fā)器可能需要特殊的安全訪(fǎng)問(wèn)權(quán)限,但是觸發(fā)器的執(zhí)行時(shí)自動(dòng)的,如果insert,update,或者delete語(yǔ)句能夠執(zhí)行,則相關(guān)的觸發(fā)器也能執(zhí)行。

    4、用觸發(fā)器來(lái)保證數(shù)據(jù)的一致性(大小寫(xiě),格式等)。在觸發(fā)器中執(zhí)行這種類(lèi)型的處理的優(yōu)點(diǎn)就是它總是進(jìn)行這種處理,而且透明的進(jìn)行,與客戶(hù)機(jī)應(yīng)用無(wú)關(guān)。

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

    6、MySQL觸發(fā)器不支持call語(yǔ)句,無(wú)法從觸發(fā)器內(nèi)調(diào)用存儲(chǔ)過(guò)程。

    ?

    總結(jié)

    以上是生活随笔為你收集整理的关系数据库——视图/存储过程/触发器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。