MySQL視圖和存儲過程


MySQL視圖和存儲過程

一. 視圖

視圖是一種特殊的表,但不包含表中應有的任何列和數據,只包含使用時動態檢索數據的查詢(即:sql查詢語句)。

使用視圖的目的,在本質上就是用來查看存儲在別處的數據。

【引例】

/*使用sql查詢*/
select cust_name,cust_contact from customers,orders,orderitems
where customers.cust_id=orders.cust_id
and orderitems.order_num=orders.order_num
and prod_id='TNT2';
  • 查詢結果
cust_name cust_contact
1 Yosemite Place Y Sam
2 Coyote Inc. Y Lee

/*創建視圖*/
create view productcustomers AS
    select cust_name,cust_contact,prod_id
    from customers,orders,orderitems
    where customers.cust_id=orders.cust_id 
    and orderitems.order_num=orders.order_num;
    
/*查詢結果*/
select cust_name,cust_contact from productcustomers where prod_id='TNT2';
  • 查詢結果
cust_name cust_contact
1 Yosemite Place Y Sam
2 Coyote Inc. Y Lee

 

從此引例中可以看出,所謂視圖就是封裝了一堆的sql查詢語句
 

⭐【作用】

  • 重用sql。
  • 簡化復雜的sql操作,封裝后可以方便的使用視圖,而不必知道它的基本查詢細節。
  • 保護數據,可以只授予表的特定部分的訪問權限而不是整個表的訪問權限。

⭐【規定】

  • 名字唯一(不能與表名和其他視圖名重名)
  • 視圖不能創建索引,也不能有關聯的觸發器
  • 視圖和表可以混着用

 
【案例一】用視圖封裝格式

/*
concat()函數
功能:將多個字符串連接成一個字符串。
語法:concat(str1, str2,...)
返回結果為連接參數產生的字符串,如果有任何一個參數為null,則返回值為null。

RTRIM(str)
返回刪除了后面空格字符的字符串str。

LTRIM(str)
返回刪除了前面空格字符的字符串str

*/
select CONCAT(RTRIM(vend_name),'(',RTRIM(vend_country),')') AS vend_title
from vendors
order by vend_name;
  • 查詢結果
vend_title
1 ACME(USA)
2 Anvils R Us(USA)
3 Furball Inc.(USA)
4 Jet Set(England)
5 Jouets Et Ours(France)
6 LT Supplies(USA)
/*創建視圖*/
create view vendorlocation as
select CONCAT(RTRIM(vend_name),'(',RTRIM(vend_country),')') AS vend_title
from vendors
order by vend_name;
/*使用視圖*/
select * from vendorlocation;

  

二. 存儲過程

先考慮這么一個問題:當我們執行某個處理需要針對許多表的多條sql語句,語句執行的順序也是不固定的,可能會隨某些數據在表中存不存在而發生變化,這個時候怎么處理?

簡單來說,存儲過程就是為了方便以后使用而事先保存的sql語句集合。

【引例】

/*
    創建存儲過程
    1. 如果需要參數,可以在()中給出,即使沒有參數,也要寫()。
    2. 用 begin 和 end 來限制執行體,end要分號結尾。
    
  */
create procedure productprice()
begin
    select AVG(prod_price) as priceAvg from products;
end;

/*調用存儲過程*/
call productprice();
  • 結果展示
priceAvg
1 16.133571

 

🌞可以將存儲過程理解成sql中的函數

 
 

【案例一】使用參數(傳出)

/*
    創建存儲過程:
    1. 此存儲過程接收三個參數:pl、ph、pa
    2. out:指出相應的參數是用來傳出去的(返回給調用者)
    3. in:調用者傳遞給存儲過程的
    4. inout:同時具備上述兩者作用
*/
create procedure productprice2(
    out pl DECIMAL(8,2),
    OUT ph DECIMAL(8,2),
    OUT pa decimal(8,2)
)
begin
    select min(prod_price) into pl from products;
    select max(prod_price) into ph from products;
    select avg(prod_price) into pa from products;
end;
/*
    調用存儲過程
    1. @用來聲明變量
    2. @pricelow,@pricehigh,@priceavg在此處用來接收返回值
    3. 該調用並不顯示任何數據,只返回變量。
*/
call productprice2(@pricelow,@pricehigh,@priceavg);

/*查看變量*/
select @pricelow,@pricehigh,@priceavg;
  • 結果展示
@pricelow @pricehigh @priceavg
1 2.50 55.00 16.13

 
 

【案例二】(傳入和傳出)

/*創建存儲過程*/
create procedure ordertotal(
    in onnumber int,
    out ototal decimal(9,2)
)
begin
    select sum(item_price*quantity) from orderitems where order_num=onnumber into ototal;
end;

/*調用存儲過程*/
call ordertotal(20009,@ototall);

/*查看變量*/
select @ototall;
  • 結果展示
@ototall
149.87

 
 
【案例三】綜合

/*
    創建存儲過程
    判斷邏輯:針對有些顧客要收營業稅,有些則不
    taxable為1則征收
    taxable為0則不征收
*/
create procedure ordertotal(
    in onnumber int,
    in taxable boolean,
    out ototal decimal(8,2)
)
begin
    -- declare variable for total 聲明一個總量(局部變量)
    declare total decimal(8,2);

    # declare tax percentage 交稅的百分比
    declare taxpercent int default 6;

    -- 銷售額=銷售總量×單價
    select sum(item_price*quantity) from orderitems
    where order_num=onnumber into total;

    -- 判斷要不要交稅;注意if格式
    if taxable then
        select total+(total/100*taxpercent) into total;
    end if;
    select total into ototal;
end;

/*不交稅的調用過程*/
call ordertotal(20005,0,@total);

/*交稅的調用過程*/
call ordertotal(20005,1,@total1);

/*展示結果*/
select @total,@total1;
  • 結果展示
@total @total1
1 149.87 158.86


免責聲明!

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



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