SQL实验报告
实验四触发器实验
(一)
after
触发器
(1 1 )
在l l i neitem 表上定义一个 after 触发器, , 当修改列项目e e x tendedprice d i scount
x tax 时, , 要把 s orders 表得to o tal pri ce e 一起修改, , 以保证数据一致性
C RE ATE T RIGGER
trig _line ite m_ pr ice_ update on line it em fo r upda te
a as
begin i f (UPDATE(ex tend edprice)
o r UPDATE(tax)
or UPD AT E(di scou nt)) begin
-— 声明游标变量指向 inserted 表
d eclare
cursor_inserted c urs or
rea d_only
o for select order key,linenu mber,exte nd edpr ice, dis coun t, tax
from
in ser ted
—-息信找查取获量变明声ﻩ 声明变量获取查找信息
de clare order key in t, @linenumb er
int,exte nd edprice
real,dis scount real,tax real
—- 打开游标 epoﻩ en cursor_i ns ert ed
—-标游取读ﻩ 读取游标
fe tch
next
from cur sor _i ns erte d int o @o rderkey, @lin enumber,e ext ende dprice, @di scount,t ax
w whi le FETC H_S TATUS =0 nigebﻩ n
ﻩ —- 声明一个变量保存重新计算得新价格 cedﻩﻩ ecl are @n ew_tota lpri ce
r eal
ﻩ select @n ew_t otal price= @ext en dedpr ice *(1 -@di scou nt) *(1 +@tax)
—- 用新得总价格变量更新 orders 表得 t ot alprice puﻩﻩ update orde rs
se t tot alpri ce= new_totalprice where or derkey=orde rkey
en hctefﻩ ext f ro m cur sor_i nser ted int o @order ke y, @li nenum ber, @ex tende dp rice,discoun t, @tax
dneﻩllaedﻩ locate c ur sor_i nser te d e end end ﻩ(2)在 在 linei tem表上定义一个 aftr er 触发器, , 当增加一项订单明细时, ,
自动修改 s orders 表得 total p rice, 以保证数据一致性
CREATE TR IGGER tri g_ lineit em_price_ in sert on l ine item f for inse rt
a s begin ——向指量变标游明声ﻩ 声明游标变量指向ins erted 表
de clare
c ursor_inse rted
cursor
read_ onl y
ﻩ for s ele ct orderkey,linenumbe r,ex te ndedp ric e,di scou nt,t ax
from ins serte d
-- 声明变量获取查找信息 edﻩ eclare @orde rk ey
int, @lin enumber int,e xten dedp rice
real, @discount
real, @ta x real -—ﻩ - 打开游标
open cursor_i ns erte d --ﻩ - 读取游标
fe tc h
nex t
f rom
cu rsor_ins erted
into
@o rd erkey,li nen umbe er r, ex ten ded pric e,dis count,tax ihwﻩ ile @@FE TCH_ STATU S=0 ebﻩ egin
-—格价新得算计新重存保量变个一明声ﻩﻩ 声明一个变量保存重新计算得新价格
cedﻩ clare @n ew_tot alprice real
celesﻩ ct new _to ta lprice= @extend edp rice *( 1-d is count) *(1+tax) —-新更量变格价总得新用ﻩﻩ 用新得总价格变量更新orders 表得totalpri ce
ﻩ u pda te
or ders s et
t ota lpric e=total pric e+ @new_ tota lpr ice w wh he re o rderke y=orderkey
tefﻩ etch next from cursor_ ins erte d into o rder key, @l inen umber,e xtended dp ric e, @disc ou nt, @t ax
e end aedﻩ deall oca te cu rsor_in serted en d
(3)
在l in e ite m表上定义一个a ft er触发器, , 当删除一项订单明细记录时, ,
自动修改 orders 表得 tot a lprice, 以保证数据一致性
CREATE TRI GG ER trig _line item_price_de let e
on line item fo r de let e
A AS begin
- -声明游标变量指向delet ed 表
de clar e curso r_d eleted cursor
re ad _on ly
es
rofﻩﻩ ele ct ord erk ey,line numbe r,extende dp rice,discoun t, tax
from
del eted -ﻩ -- 声明变量获取查找信息
declare ord erkey int,linenum be r
int,extendedp ri ce r eal,discou nt real,ta x real -—ﻩ -
打开游标 epoﻩ en c urso r_ deleted
——标游取读ﻩ 读取游标 efﻩ etch next fr om cur sor_delete d in to
order ke y,l inenumb er,ext end dedprice, @di scoun t,tax
wh ile @FETCH_STATUS=0
begi n
-— 声明一个变量保存重新计算得新价格
ﻩ declare @ne w_ to talpric e real
ﻩ s selec t @new_t otalpr ice= @exte nde dpri ce*(1- @disco unt) *(1+ tax)
-ﻩ -— 用新得总价格变量更新orders 表得tot alp rice uﻩﻩ upd ate
orders set t otalpri ce=to talpr ice- @new _totalp rice wh er e order key= @ord erkey
fetch
n ext f rom cursor_inse rt ed in to orderkey, @line numbe r,extende ed dprice, @d iscou nt,t ax dneﻩ nd
d deal lo cat e cur sor_inse rted e end ( (4 4) ) 验证 up d at e触发器
— -查瞧 号订单得 to ta a l pr i ce
selec t
*
fro o m
o o r ders where
orde r key=1 8 30;
— -查瞧明细表得相关信息
se l ect *
f ro m
lin ei i te e m
w here or de e r key=183 0
and l ine num m be e r =1;
—— 验证 e update 触发器
updat e
lineitem set t ax=tax+0 、 05
whe re orderkey=1830;
(二)
i i n stead
of
触发器
( (1)
)
在 在 lineit em 表上定义一个ins tead o f upda te触 发器, 当修改明细表中得数量 量quan ti ty 时, 应先检查供应表par tsupp 得av ai lqty 就是否足够, 不足够则拒绝执行, 否则执行并修改相应数值以保证数据一致性 于 由于 in stead
of 触发器更新某个表会使得该表上其她不满足更新列不能更新,因 因用 此逆向思维使用 a fter 触发器实现相同效果 即先更新 qu antity, 再比较av ailq qt ty, 如果满足更新数量, 就修改partsupp 得 表得 a vailqty, 如果不满足, 则把lineitem得quantity 更新之后得数据重新修改回来 c create trigge r trig_lin eit em_quanti ty_ upda te
on
li neit em f or upda te
as begin if UPDATE(qu ant ity) b begin ——向指别分量变标游明声ﻩ 声明游标变量分别指向 i nserted 表与 d el eted 表 edﻩ declare c urso r_inser ted
cur sor
r ead_on ly
for
tcelesﻩﻩ t
orde rkey, partk ey,s uppkey,lin enum ber, quantit y fr om i nserted
decl are
cursor_de leted c urs or
rea d_ onl y
f or select quantity
fr om deleted
-—息信找查取获量变明声ﻩ 声明变量获取查找信息
decl are
@qu an tity _dif f_lineitem i nt,q uanti ty_pa rtsup p i nt cedﻩ clare suppkey int, @par tke y in t,o rd erkey i nt,
unenilﻩﻩ um ber int ,qty _inserted in t , @qty_delete d int
- - 打开游标 ruc nepoﻩ rsor_in sert ed poﻩ open cur sor_d eleted
-—量变给赋值数标游取读ﻩ 读取游标数值赋给变量 fﻩ fet ch next from
cu rsor_ insert ed
ﻩ i into or de rk ey,pa rtkey, @suppk ey, @line nu mber, @qty _ins erte d
f et ch
next from
cursor _d eleted
int o q ty _de lete d
whi le fe tch_st atus=0 gebﻩ egin
- -计算订单明细修改时, 订购数量得变化值 inserte d表项-d elet ed表项
s sel ect quantity_d if f_ li neit em= @q ty _in se rte d—@ @q ty_delete ed
ﻩ --从parts upp 表获取ava ilq ty值, 注意partsupp 表得主键为(partk ey,suppke ey) tcelesﻩﻩ t @quanti ty_p ar tsupp =av ailq ty fro m pa rtsu pp
wﻩﻩ wh er e suppkey= suppke y
and part key= @par tk ey
-—断判始开ﻩﻩ 开始判断
gebﻩ begi n
fiﻩ f quant ity _d iff_ lin eite m=0
ﻩ
ﻩ p rin t " 更新得数量与原表中得值相同, 不需要更新"
e ls e if @quantit y_d iff_lin eitem 〈=q uantity_partsupp
ﻩ
be gin
ﻩ puﻩﻩ pd ate partsupp
s et avail qty= availqty- @qua ntit y_d iff_li ne item
ﻩ pus erehwﻩ ppkey=suppkey
and
p artkey= @par tke y
ﻩ
ﻩ p rint " 两个表都更新成功’ ﻩ
ﻩﻩneﻩ nd
els e
igebﻩﻩ in
ﻩ uﻩﻩ update li nei tem
set
quantit y=quantity+ @quanti ty_diff_linei tem
whe re o rd erke y=@orde rke y and li nenu mber= @li ine number
ﻩ
p ri nt '更新失败"
ﻩﻩ end
ﻩ e nd efﻩﻩ etch ne xt
fr om c urso r_i nserted
i nto @ord erke y, @partkey,s upp key, @linenumb er, @qt y_ ins ert ed
f etch ne xt from curso r_de leted into @qt y_d elet ed dneﻩ nd
d eallocat e cur sor _i nserte d
dealloc at e cursor_de le ted e end e end (2)在 在 l ineite m表上定义一个 instea d of in sert 触发器, 当插入明细表中一条记录 时 时, 应先检查供应表par tsupp 得 得 ava il qt y就是否足够 qu anti ty 得数量 c rea te t rig ger tri g_lineitem_q ua nti ty_ insert
on
line item i instead of inser t as b begin
-— 声明游标变量指向 inserte d表
d eclar e cur sor_inserte d cur sor
rea d_ only f or
sﻩﻩ select or derk ey,pa rtkey,sup pk ey, lin en umber,q uantity
f rom ins er ted
-—
声明变量获取查找信息
dec lare quantity int, @av ailq ty i nt, @suppkey
in t, @partkey
in nt t, @o rderkey int, @linenu mber int
-—标游开打ﻩ 打开游标 c nepoﻩ curs or_ins erted -ﻩ -— 读取游标
f etc h next fro m cursor_insert ed int o @orde rkey,partkey,@ @s suppkey, @linenumber,qu antity
wh ile @@FETCH_S TATUS= 0 igebﻩ in
-- 为变量赋值
a tcelesﻩ availqty y
= =av ai lqt y fr om
partsupp
wﻩ whe re suppkey =@su ppk ey and part ke y= partke y
ﻩ if @quant ity 〈= @avail qt y
-— 如果可以更新
bﻩ begin /ﻩﻩﻩ /*将 将 insert ed 表中得记录插入到明细表*/
ﻩ sniﻩ sert
i nto l ineite m select *
from i nserted
ro=yekredro
erehwﻩﻩ rderk ey and
linenumb er = @linenumber */ﻩﻩ新更时同ﻩ *同时更新 part supp 表得数量*/
ﻩﻩ u upd ate pa rtsup p set a vailqty=availqty- @quanti ty
ﻩ
erehwﻩ e sup pke y= @sup pkey and partkey=part key
p pr int ’pa arts upp 表有足够得货物可以满足 lin eitem 得quan tity y, 插入成功’
end
else
begin
ﻩﻩ p rint t
' 'pa rt sup p表没有足够得货物可以满足 l ineitem 得 得 q uantity,插入失败’
dneﻩfﻩﻩ fetc h next from curso r_ins ert ed in to @ord erkey, partkey, suppkey, @li inenumbe r, qu antity eﻩ en d
deall ocat e cursor_ inserted end ( 3)在 在 line ite m表上定义一个 inste ad of del ete 触发器,当 当 删除 明细表中记录 时 时, 同时改变表 供应表 partsupp 得ava il qty y 数值 c re ate trigge r tri g_ lin eit em_quanti ty_ del ete o n line item inste ad of del ete as be gin
—- 声明游标变量指向deleted 表
de cla re curs or_ del eted c ursor
read _only for
lesﻩﻩ elect or derke y, par tkey,sup pkey, linenumbe r,quan tity fr om deleted -ﻩ -- 声明变量
decl are s upp key i nt, par tke y
int, @orde rkey int,linen umb er
int, @qua ant it y int
—-标游开打ﻩ 打开游标
open
cursor_deleted
-—标游取读ﻩ 读取游标
f fetch next fr om
curs or _del et ed
in to @ord erkey , @partkey,s uppke ey, @lin en umber,q ua ntity
whi le
F FET CH_ STATUS=0 igebﻩ in
*/*除删ﻩ *删除*/
ﻩ de let e from
lineite m where linenu mber= line number and o rde rkey =ord der key
*/新更时同ﻩ 同时更新 pa rt supp 表得数量*/
u pdate
parts upp se t
availqt y=a vai lq ty+quant ity
ﻩ where s uppke y= @s uppkey a nd par tk ey= @p ar tkey
ﻩ p rin t
’ 删除成功, 并且已经把货物数量归还到 p ar tsup p里" fﻩﻩ fetc h ne xt fr om
curso r_del eted
into @ord er ke y
,p ar tkey,@ @suppkey, @lin enu mber,quanti ty neﻩ nd edﻩ ea lloc ate cursor_ delete d end (4) 验证 update 触发器 -- 查瞧li neit em 得quan tit y select *
fr om
lin eit em whe re or derk ey =1830
and li nenum ber=1;
—— 查询partsupp 表得ava ilqt y se lect * from part supp w here suppk ey =(select
supp key fr om
lin e
item w here ord erkey=18 30)
and partk ey
=(s elec t part key from lin eite m wh er e
order key =18 30 a nd linenu mber=1)
-- - 更新数量过大
—— 更新得值与原值相同
-- - 更新到+ + 2 00 数量, , 成功
update
li neitem set
quant ity
=q uanti ty+ 200
where order key=1830
and lin en umber = 1;
-- 更新 +2 00 成功后l ineite m得 quanti ty y 变化
—— 更新+200 成功后par ts upp 表得a va ilqty 变化
实验到此。所有创建得触发器结果
删除触发器
dr op trigger tri g_li nei tem_de lete; 实验六存储过程实验
(1 1 )
定义无参数 得存储过程并执行
更新所有订单总价
goﻩ
CREATE
PROCED URE Pro c_Ca lTotalP ri ce
AS BEGIN
up date
o rders set to talprice =
(sele ct sum( exte ndedprice*(1-discount)*(1+ tax))
ﻩ fr om li nei tem
o
erehwﻩ orders 、orderkey= li neite m。o rderke y) END
go 执行此存储过程
exec P ro c_CalTotal Pric c e; ;
(2 2 )
定义有参数得存储 过程并执行
更新给定订单号得总价
g go create pro cedu re P ro_Cal TotalP rice 4Ord er @id_ order
intege r a as be gin
u up date e
o orders set total price=(
lesﻩ lect SU M(ext en ded price*(1 -di sc ount)*(1 +tax))
ﻩ fr om li neit em
ﻩ whe re
orde rs 。or derke y=lin eite m。orderkey) end g o 执行此存储过程 exe c P ro_ CalTota lPr ice 4Order @id_ order=2; ( (3)
)
定义有局部变量得存储过程 更新某一个顾客所有订单得总价 g o cr eate
procedure Proc_Ca lTot alPr ice4Custo me r n ame _cus to mer varc har( 50) as
dec lare cus tk ey _c usto mer i nt b egin tcelesﻩ t
cus tke y_cu stomer=cu st key
from
cu sto mer
where name _customer =RTRI M(n ame)
u pdate order s set to talp ri ce=( tcelesﻩﻩ t S UM(exte nde dp rice *(1 -dis count)*(1+tax)) rfﻩﻩ rom li neite m
wﻩ wher e orders 、order key=lineitem 。or derke y
ﻩ and
o rde rs 、cust key= @c ustkey _cust omer) ﻩe nd go 执行此存储过程
e xec Pro c_CalT ot alPr ic e4C ustome r name_custom er=" 艾锦亮’; 查瞧结果 u pdate
linei te m set
ex tende dpric e=1 00 , ta x=0.25 where orderkey="1 830’; s elect * from
l ineite m
w here order key ='183 0’;
s elect * fr om or ders wh ere custke y= (sele ct cus tk ey from custo mer whe re name=’ 艾锦亮’);
(4 )
定义一个带输出参数得存储过程 更新某个顾客得所有得订单总价, 并输出总价 go crea te proc edure Proc_C alT otalP ri ce4Custo me r2
na me_ cu st ome r va rch ar( 50), totalpr ice_ord er real out put
as —— 声明一个变量存储 name 对应得顾客编号 d eclar e @c us tkey _cus tomer integer
—— 为该变量赋值
se lec t c ustke y_cu sto mer =cu stkey
from cus tome r w here n ame_ customer=R TRIM(n ame) begi n -ﻩ -- 更改订单总价
up date
o rd ers
set t otalp rice=(
se lec t SUM(ext endedprice*(1-dis count)*( 1+tax))
fﻩ fr om l in eitem rehwﻩﻩ ere
orders 。o rderk ey=li neit em.ord erk ey
、sredro dnaﻩ 、c ustkey =@custkey_ custome r)
-— 为返回变量赋值
select
totalprice_order=total pri ce fro m orders
ﻩ w here custk ey= @c ustkey_c ustom er
ﻩ
e nd go —- 执行带有输出参数得存储过程要声明输出参数变量 declare t otalp rice re al ; exe c Proc_ Cal Tota lPrice4C ustomer2
" 艾锦亮 ', @to talpri ce
output; -- 在屏幕上输出返回值结果
selec t t otalpri ce;
实验到此, , 所有结果显示
(5 5 )
修改存储过程名
exec sp_renam e ’Pr o_Cal TotalPrice4Ord er",
’C alTotalPr ice4 Or der';
(6) 编译存储过程
exe c sp_ re compile ’CalTotalPric ce 4Order’;
(7) 删除存储过程
d drop
proc edure CalT otalPric e4Orde r; e exe c sp_h elptext CalT ot alPrice4 Order;
上一篇:图实验报告
下一篇:小学校长述职报告-述职报告