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 |