MySQL(十一)視圖及存儲過程


一、視圖

視圖是虛擬的表,它只包含使用時動態檢索數據的查詢。

1、使用視圖的好處

重用SQL語句;

簡化復雜的SQL操作(可以方便的重用它而不必知道它的基本查詢細節);

使用表的組成部分而不是整個表;

保護數據(可以給用戶授予表的部分訪問權限而不是整個表的訪問權限);

更改數據格式和表示(視圖可返回與底層表的表示和格式不同的數據)。

PS:因為視圖不包含數據,所以每次使用視圖,都必須處理執行所需的任何一個檢索;如果使用了多個聯結和過濾創建了復雜的視圖或嵌套視圖,性能下降比較明顯。

 

2、視圖的規則和限制

視圖必須唯一命名(視圖與別的視圖或表不能有相同的名字);

創建的視圖數目沒有限制;

為了創建視圖,必須有足夠的訪問權限;

視圖可以嵌套;

order by也可用於視圖;但如果該視圖中檢索數據的select語句包含order by,那么該視圖中的order by將被覆蓋;

視圖不能索引,也不能有關聯的觸發器或默認值;

視圖可以好表一起使用。

 

3、使用視圖

create view:創建視圖;

show create view viemname:查看創建視圖的語句;

drop view viewname:刪除視圖;

PS:更新視圖時,可以先用drop再用create,也可以直接使用create or replace view;如果要更新的視圖不存在,則第二條更新語句會創建一個視圖,如果視圖存在,則第二條更新語句替換原有視圖。

3.1簡化復雜的聯結

視圖最常見應用之一就是隱藏復雜的SQL,通常會設計聯結;例如:

create view productcustomers AS

select cust_name,cust_conact,prod_id

from customers,orders,orderitems

where customers.cust_id = order.cust_id

and orderitems.order_num = order.order_num;

這條語句創建一個名為productomers的視圖,聯結三個表,以返回已訂購任意產品的所有客戶的列表。如果執行select * from productcustomers,將列出訂購了任意產品的客戶。

為了檢索出訂購了產品TEST的客戶,可如下進行:

select cust_name,cust_contact

from productcustomers

where prod_id = 'TEST';

這條語句通過where子句從視圖productcustomers中檢索特定的數據。

PS:視圖可以極大的簡化復雜SQL語句的使用,利用視圖,可一次性編寫基礎的SQL,然后根據需要多次使用。

3.2重新格式化檢索出的數據

視圖的另一個常用功能就是重新格式化檢索出的數據,比如:

create view vendorlocations AS

select concat(RTrim(vend_name),'(',RTrim(vend_country),')')

AS vend_title

from vendors

order by vend_name;

這條SQL語句使用select語句創建視圖,在單個組合計算列中返回供應商名和位置,以后每次需要時使用這個視圖即可。

3.3使用視圖過濾不想要的數據

視圖對於普通的where子句也很有用,例如:

create view customeremaillist AS

select cust_id,cust_name,cust_email

from customers

where cust_email is not NULL;

這條SQL語句定義了customeremaillist視圖,它過濾沒有電子郵件地址的客戶。

PS:如果從視圖檢索數據時使用一條where子句,則兩組子句(一組在視圖中,另一組是傳遞給視圖的)將自動組合。

3.4視圖與計算字段

視圖對於簡化計算字段來說,也很有用,例如:

create view orderitemsexpanded AS

select order_num,prod_id,quantity,item_price,

quantity*item_price AS expanded_price

from orderitems;

這條語句創建了orderitemsexpanded視圖,它檢索某個特定訂單的物品以及每種物品的總價格,如果需要使用該視圖,只需要執行一條select語句即可,比如:

select * from orderitemsexpanded where order_num = 10086;

3.5更新視圖

通常來講,視圖是可更新的,更新一個視圖即更新其基表(如果MySQL不能正確的確定被更新的基數據,則不允許更新(包括插入和刪除));即視圖如果定義如下操作,則不可更新:

①分組(使用group by和having);②聯結;③子查詢;④並;⑤聚集函數(min()、count()、sum()等);⑥distinct;⑦導出列。

 

二、存儲過程

定義:為方便以后使用而保存的一條或多條MySQL語句的集合,可將其視為批文件(雖然其作用不僅限於批處理)。

1、為什么要使用存儲過程(簡單、安全、高性能)

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

②不要求建立一些列處理步驟,保證了數據的完整性;

③簡化對變動的管理(如果表名、列名或業務邏輯變更,只需要更改存儲過程的代碼),這一點的延伸就是安全性;

④提高性能(使用存儲過程比使用單獨的SQL語句要快);

2、使用存儲過程

①執行存儲過程

MySQL中一般將存儲過程的執行稱為調用,執行的語句用call,call接受存儲過程的名字以及傳遞給它的任意參數;例如下面的例子:

call productpricing(@pricelow,

                    @pricehigh,

                    @priceaverage);

這條SQL語句中,執行名為productpricing的存儲過程,並計算返回產品的最低、最高和平均價格(存儲過程可以顯示結果,也可以不顯示)。

②創建存儲過程

下面創建一個返回產品平均價格的存儲過程,例子如下:

create procedure productpricing()

begin

       select avg(prod_price) as priceaverage

       from products;

end;

此存儲過程名為productpricing,用create procedure productpricing()語句定義;如果存儲過程接受參數,它將在()中列舉出來,此存儲過程沒有參數,但后跟的()仍然需要。

begin和end語句用來限定存儲過程體,過程本身僅是一個select語句以及avg()函數。

注意事項:MySQL命令行客戶機的分隔符

默認的MySQL語句分隔符為;。如果命令行實用程序要解釋存儲過程自身內的;字符,則他們不會成為存儲過程的部分,這樣會使存儲過程中的SQL出現語法錯誤;解決辦法如下:

delimiter//

create procedure productpricing()

begin

       select avg(prod_price) as priceaverage

       from products;

end//

delimiter;

其中,delimiter//告訴命令行實用程序使用//作為新的語句結束分隔符;如果要恢復原來的分隔符,可使用delimiter(除/之外,任何字符都可以用作語句分隔符);

③刪除存儲過程

比如:drop procedure productpricing;

這條語句刪除剛才創建的存儲過程;注意,后面沒有使用(),只給出存儲過程名。

PS:如果指定的存儲過程不存在,則drop procedure將產生一個錯誤;當存儲過程存在,想刪除他時,可以使用drop procedure if exists.

④使用參數

一般來講,存儲過程不顯示結果,而是把結果返回給指定的變量(變量內的一個特定的位置,用來臨時存儲數據)。

下面是上面的存儲過程的修改版本:

create procedure productpricing(

       out p1 decimal(8,2),

       out ph decimal(8,2),

       out pa decimal(8,2)

)

begin

       select min(pro_price)

       into p1

       from products;

       select max(prod_price)

       into ph

       from products;

       select avg(prod_price)

       into pa

       from products;

end;

此存儲過程中接受3個參數:p1存儲產品最低價格,ph存儲產品最高價格,pa存儲產品平均價格;關鍵字out指出相應的參數用來從存儲過程傳出一個值(返回給調用者);

PS:MySQL支持in(傳遞給存儲過程)、out(從存儲過程傳出)和inout(對存儲過程傳入和傳出)類型的參數。

為了調用上面修改過的存儲過程,必須指定3個變量名,如下:

call productpricing(@pricelow,

                    @pricehigh,

                    @priceaverage);

PS:所有存儲過程的變量都必須以“@”開始。

調用時候,上面的調用語句並不現實結果,它返回以后可以顯示的變量;為了顯示檢索出的價格,使用下面的語句:

select @pricelow, @pricehigh, @priceaverage;

⑤檢查存儲過程

為了顯示創建存儲過程的create語句,使用show create procedure語句,比如:

show create procedure ordertotal;

如果想獲得詳細的關於存儲過程的信息,比如創建時間、創建人等信息,使用show procedure status。

PS:show procedure status列出所有存儲過程,為限制其輸出,可使用LIKE指定一個過濾模式,例如:

show procedure status like 'ordertotal';

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM