數據庫之MySQL(MySQL學習筆記)——數據庫視圖、觸發器、存儲過程

數據庫視圖

  • 什麼是視圖?
    視圖是虛擬表,是對實表的一種映射。
    視圖還可以從已經存在的視圖的基礎上定義。

  • 視圖的作用?
    簡單性、安全性、邏輯數據獨立性
    簡單來說:(1)對複雜的sql進行封裝
    (2)對數據庫敏感信息的保護

  • 視圖的創建
    注意:
    (1)視圖使用上就和正常的數據表一樣
    (2)視圖在MySQL中擁有和實體表一樣的地位

    題目:製作一個視圖提供給銷售人員,他們只需要知道商品名稱、出售價格、商品的類型 產地信息即可

create view view_sellset as #view 創建視圖 	view_selletset 視圖名稱 
select c.c_name as 商品名稱 ,c.c_madein as 商品產地 , ct.ct_name as 商品類型 ,c.c_outprice as 商品售價
from commodity as c inner join commoditytype as ct on c.c_type=ct.ct_id where c.c_outprice is not null;

創建視圖
查詢視圖中的商品名稱,商品售價

select 商品名稱,商品售價 from view_sellset;

查詢
修改:因爲視圖是實表的一種映射,所以通過視圖修改表中的數據就是修改實表中的數據。
注意:因爲這裏的用戶名是root,纔有權限進行修改;否則是不能進行修改的。

update view_sellset set 商品售價=20 where 商品名稱='變形金剛-擎天柱';	#修改變形金剛-擎天柱的售價爲20,原來爲50;
select * from commodity where c_name='變形金剛-擎天柱';

修改

三大範式

(1)第一範式
每一列屬性都是不可再分的屬性值,確保每一列的原子性。
(2)第二範式(確保表中每列都和主鍵相關)
一張數據表至少有一個主鍵。
(3)第三範式(確保每列都和主鍵列直接相關,而不是間接相關)
一張數據表有且只有一個主鍵

觸發器

  • 觸發器創建語法的四大要素:
    (1)監視地點(table):基於表,表示對哪張表進行監控
    (2)監視事件(insert/update/delete):用來監視執行的語句
    (3)觸發時間(after/before):在執行命令之前/之後
    (4)觸發事件(insert/update/delete):執行的MySQL的命令語句
  • 觸發器new old
    (1)insert語句,只有new是合法的。
    (2)delete語句,只有old是合法的。
    (3)update語句,new和old可以同時使用
  • 觸發器(插入)
    往訂單表中插入數據的觸發器
    delimiter:更換標識符
    create trigger tri_1:創建觸發器
    begin and相當於{}
delimiter $
create trigger tri_1
after insert on `order`
for each row 
begin 
update commodity set c_num=c_num-new.o_num where c_id=new.o_cid;
end$
delimiter ;

觸發器(插入)

select c_name,c_num from commodity where c_id=12;	#先查詢商品表中id=12的商品名字,庫存
insert into `order` (o_cuid,o_cid,o_num) values (1,12,2);#增加訂單表,買了12號商品2個
select c_name,c_num from commodity where c_id=12;#再次查詢商品表中id=12的商品名字,庫存

插入結果-1
插入結果-2

  • 觸發器(修改)
delimiter $
create trigger tri_3
after update on `order`
for each row 
begin 
update commodity set c_num=c_num+old.o_num-new.o_num where c_id=old.o_cid;	#c_num就等於把原來購買的數量加回去然後再減去修改後要買的數量
end$
delimiter ;

觸發器(修改)

select * from `order`;	#查詢訂單表,找到要修改的訂單id
update `order` set o_num=3 where o_id=8;	#修改訂單
select c_name,c_num from commodity where c_id=12;	#修改後查詢庫存

修改結果

  • 觸發器(刪除)
delimiter $
create trigger tri_2
after delete on `order`
for each row 
begin 
update commodity set c_num=c_num+old.o_num where c_id=old.o_cid;	#就是把訂單表中的值+現在的庫存
end$
delimiter ;

觸發器(刪除)

select * from `order`;	#查詢訂單表,找到要刪除的訂單id
delete from `order` where o_id=8;	#刪除訂單
select c_name,c_num from commodity where c_id=12;	#刪除後查詢庫存

刪除結果

存儲過程

create procedure sp_name(proc_parameter[...])
begin
[characteristic ...] routine_body
end

sp_name:存儲過程名稱
proc_parameter:存儲過程的參數列表
characteristic:存儲過程的特性
routine_body:SQL語句的內容,可以用begin…end來標誌SQL語句的開始和結束

delimiter $
create procedure pro_queryall()	#創建存儲過程
begin 
select * from commodity;	#存儲過程的特性
end$
delimiter ;
 
call pro_queryall();	#輸出存儲過程的結果
  • 簡單的存儲案例(查詢商品表)
    查詢商品表
  • 傳入in參數的存儲案例
delimiter $
create procedure pro_ask(in cu_id int(11))	#傳入參數用in,傳入的數據類型要和表中的保持一致
begin 
select c_name from commodity where c_id in (
select o_cid from `order` where o_cuid = cu_id);	#查詢客戶購買的所有商品
end$
delimiter ;

call pro_ask(1);

傳入in參數

  • 傳入out參數的存儲案例
delimiter $
create procedure pro_askcnum(in cid int(11),out cnum int(11))	#傳入參數時注意不要和表中的字段名一樣
begin 
select c_num into cnum from commodity where c_id = cid;	#通過商品id得到商品的庫存
end$
delimiter ;


set @cn=-1;	#用來接out傳出的值
call pro_askcnum(12,@cn);
select @cn;

傳入out參數

  • 綜合練習
    題目:使用存儲過程完成 訂單數據的新增
#插入
delimiter $ #修改結束標識符	
create proceduce `insertOrder`(in _o_cuid varchar(50),in _o_cid varchar(50),in _o_num int,out flag int(11))
begin
	set @_c_num=0;	#用來存儲c_name的值
	set autocommit=0;	#關閉自動提交
	start transaction;	#開始一個事務標記點
	insert into `order` (o_cuid,o_cid,o_num) values (_o_cuid,_o_cid,_o_num);	#傳入客戶id,商品id,購買的數量
	set @_c_num=(select c_num from commodity wherec_id=_o_cid);	#通過觸發器後得到購買後商品中庫存的量
		IF @_c_num>=0 			#如果庫存大於0,提交訂單
			then commit;
			set flag = 1;		#設置flag=1就是成功,0就是失敗
		else rollback;			#否則,回滾
			set flag = 0;
		end if;
	set autocommit=1;		#開啓自動提交
end$
delimiter ;	#修改標識符

#修改,邏輯和以上代碼思維一致
delimiter $
create proceduce `updateOrder`(in _o_id int(11),in _o_num int(11),out flag int(11))
begin
	set @_c_num=0;
	set autocommit=0;
	start transaction;
	update `order` set o_num=_o_num where o_id=_o_id;
	set @_c_num=(select c_num from commodity where c_id=(select o_cid from `order` where o_id=_o_id));
		IF @_c_num>0 
			then commit;
			set flag = 1;
		else rollback;
			set flag = 0;
		end if;
	set autocommit=1;
end$
delimiter ;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章