sql触发器实验
- 格式:doc
- 大小:71.00 KB
- 文档页数:4
数据库触发器实验创建基于表的触发器。
--删除已经存在的表T_TRIG。
DROP TABLE IF EXISTS T_TRIG;--删除已经存在的表T_TRIG_LOG。
DROP TABLE IF EXISTS T_TRIG_LOG;--删除已经存在的序列TRIG_LOG_SEQ。
DROP SEQUENCE IF EXISTS TRIG_LOG_SEQ;--删除已经存在的触发器TRIG_AFTER_INSERT。
DROP TRIGGER IF EXISTS TRIG_AFTER_INSERT;--删除已经存在的触发器TRIG_BEFORE_INSERT。
DROP TRIGGER IF EXISTS TRIG_BEFORE_INSERT;--创建表T_TRIG。
CREATE TABLE T_TRIG (ID INT, CREATE_DATE TIMESTAMP);--创建表T_TRIG_LOG。
CREATE TABLE T_TRIG_LOG (LOG_SEQ INT,LOG_DESC VARCHAR(30), CREATE_DATE TIMESTAMP);--创建序列TRIG_LOG_SEQ。
CREATE SEQUENCE TRIG_LOG_SEQ START WITH 1 INCREMENT BY 1;CREATE OR REPLACE TRIGGER TRIG_AFTER_INSERT AFTER INSERT ON T_TRIGBEGININSERT INTO T_TRIG_LOG VALUES(TRIG_LOG_SEQ.NEXTVAL,'after insert',systimestamp); END;/--创建一个触发器,在往T_TRIG表中INSERT一条记录之前,往T_TRIG_LOG中写一条描述为"beforeinsert"记录。
CREATE OR REPLACE TRIGGER TRIG_BEFORE_INSERT BEFORE INSERT ON T_TRIGBEGININSERT INTO T_TRIG_LOG VALUES(TRIG_LOG_SEQ.NEXTVAL,'before insert',systimestamp); END;/--往T_TRIG表中INSERT一条记录。
试验报告实验八触发器 10信管2班胡旭强实验目的:1.掌握触发器的概念和分类。
2.掌握创建,删除,查看,修改触发器的操作。
实验环境与方法:环境:SQL SERVER 2005方法:使用查询分析器实验要求:学习编写自己的触发器,并在相应的操作下引发触发器实验内容与步骤:1.基于CUSTOMER表创建一个触发器,针对INSERT,DELETE,UPDATE操作。
当执行INSERT,UPDATE 语句时,将INSERTED表中的数据打印出来,当执行DELETE,UPDATE语句时,将DELETED表中的数据打印出来。
2.建立删除触发器,删除产品表product中的产品时,把相关表中的数据一起删除(proinproout)3.为proout表建立一个插入触发器,当向表中插入记录时,检测CUSTOMER表和product表中是否有记录存在,如果有,则插入记录,否则,显示不能插入。
4.建立触发器,要求即时得到每种产品的库存数量.实验注意事项:1.建立触发器时,SQL SERVER 2005自动创建和管理的两个特殊表,INSERTED,DELETED2.使用SQL语句编写自己的触发器1. create trigger cc_1 on customerfor INSERT,DELETE,UPDATEasif exists(select*from inserted)print'insert'select*from insertedif exists(select*from DELETEd)print'DELETE'select*from DELETEdgo2. create trigger cc_5 on productfor deleteasdeclare @ms char(5)select @ms=prono from deletedprint'开始查询并删除相关表中的数据'delete from proout where prono=@msprint'删除proout的记录数为'+str(@@rowcount)delete from proin where prono=@msprint'删除proin的记录数为'+str(@@rowcount)go3.create trigger cc_3 on prooutfor insertasbegin trandeclare @a char(3),@b char(3)select @a=cusno,@b=prono from insertedif exists(select*from customer where cusno=@a) beginif exists(select*from product where prono=@b) begincommitprint'可以插入'endelsebeginrollbackprint'不可插入,无此类产品'endendbeginrollbackprint'不可插入,无顾客'endgo4. create trigger cc_4 on proinfor insertasdeclare @qy decimal(6,0),@pr char(5)select @qy=quantity,@pr=pronofrom insertedupdate productset stocks=stocks+@qywhere prono=@prgo。
--建立触发器,显示修改人数create trigger d1 on jun for insert,update asselect '你正在修改数据'declare @a varchar(20)select @a=str(@@rowcount)+'个学生被修改'select @aselect * from junreturninsert into jun(爱好) values('跑步')update jun set 爱好='打球' where 学号<='103'--建立触发器,当男生人数在6个以内可以加入,否则不能加入create trigger i1 on zg for insert asif((select count(性别) from zg where 性别='男')>6)select '不能插入,男生人数已满。
'elseselect'插入成功'select * from zginsert into zg(学号,姓名,性别) values(20100636,'江渝','男')--建立触发器,如果语文成绩在200以内可以修改,否则不能修改create trigger u1 on zg for update asif((select max(语文) from zg )>200)beginselect '你不能修改'rollbackendelseselect '修改成功'select * from zgupdate zg set 语文=语文+10 where 姓名='唐荣强'update zg set 语文=语文-20 where 姓名='张军'update zg set 语文=语文+30 where 姓名='张军'--建立触发器,显示删除和修改的内容create trigger d2 on zg for insert,update,delete asselect * from deletedselect * from insertedselect * from zgdelete from zg where 班级=Nulldelete from zg where 姓名='张军'--建立触发器,如果zg表中没有此人的姓名,则不能在kc表中进行修改create trigger i2 on kc for insert,update asif(not exists(select 姓名from zg where 姓名=(select 姓名from inserted))) beginselect '不能修改数据'rollbackselect * from kcendelsebeginselect '修改成功'select * from kcendupdate kc set 选修人数=选修人数+100 where 姓名='张军'--建立触发器,更行zg时也更新kccreate trigger u2 on zg for update asselect * from deletedselect * from insertedupdate kc set 姓名=(select min(姓名) from inserted )where 姓名=(select min(姓名) from deleted)select * from zgselect * from kcupdate zg set 姓名='张晓军' where 姓名='张军'--建立触发器,如果加入的数>2000就不能插入并将默认值为500create trigger i3 on zg for insert asif((select 语文from inserted)>2000)beginselect '语文>2000不合适'update zg set 语文=500select * from zgrollbackendelseselect '修改成功'insert into zg(班级,姓名,学号,语文) values('小数','王五',20100637,2500)--建立触发器,不能删除总成绩最高的人create trigger d3 on zg for delete asif( select 总成绩from deleted) >= ( select max(总成绩)from zg)beginselect '删除的数为:'select * from deletedselect '不能删除成绩最高的一位'rollbackendelseselect '删除成功'select * from zgdelete from zg where 姓名='唐荣强'--建立触发器,英语增长不超过250%create trigger u3 on zg for update asif(select max(英语) from inserted )/(select min(英语) from deleted)>2.5beginselect * from deletedselect * from insertedselect '增长速度>250%不能修改'rollbackendelseselect '修改成功'select * from zgupdate zg set 英语=英语*3 where 姓名='杨杰'--通过触发器调用其他函数create proc p1 asselect * from zgcreate trigger u4 on zg for insert,delete,update asexec p1insert into zg(姓名,学号,班级)values('小王',20100638,'小语')--多个触发器运行顺序create trigger i5 on zg for insert,update asselect '你在插入数据'create trigger u5 on zg for update,insert asselect '你在修改数据'update zg set 姓名='张军' where 姓名='张晓军'--触发器create trigger j1 on kc for update,delete,insertasselect( '你正在修改数据');select * from deleteddelete from kc where 课程名称='计算机导论'insert into kc (学号,课程名称,课程代码,学分) values('1010','计算机导论','D032T',2) update kc set 学号=1007 where 学号=1006create trigger j2 on kc for deleteasdeclare @count varchar(20)select @count=str(@@rowcount)+'个学生被删除'select @countreturndelete from kc where 学分=1.5create trigger j3 on jun for insert,updateasif(select sum(年龄) from jun )>400beginselect '你们年龄大入要求:不予录取'rollbackendelsebeginselect '恭喜你,你被录取了'endinsert into jun (学号,爱好,年龄) values('111','编程',20)update zg set 总成绩=语文+数学+英语select * from zgcreate trigger y2 on zg for insert,updateasif( select sum(总成绩) from zg )>2000beginselect ' 你通过了考试,欢迎你晋级'rollbackendelseselect '很抱歉,你没有通过考试'select * from zgupdate zg set 语文=语文-50 select 语文from zg。
--建立触发器,显示修改人数create trigger d1 on jun for insert,update asselect '你正在修改数据'declare @a varchar(20)select @a=str(@@rowcount)+'个学生被修改'select @aselect * from junreturninsert into jun(爱好) values('跑步')update jun set 爱好='打球' where 学号<='103'--建立触发器,当男生人数在6个以内可以加入,否则不能加入create trigger i1 on zg for insert asif((select count(性别) from zg where 性别='男')>6)select '不能插入,男生人数已满。
'elseselect'插入成功'select * from zginsert into zg(学号,姓名,性别) values(20100636,'江渝','男')--建立触发器,如果语文成绩在200以内可以修改,否则不能修改create trigger u1 on zg for update asif((select max(语文) from zg )>200)beginselect '你不能修改'rollbackendelseselect '修改成功'select * from zgupdate zg set 语文=语文+10 where 姓名='唐荣强'update zg set 语文=语文-20 where 姓名='张军'update zg set 语文=语文+30 where 姓名='张军'--建立触发器,显示删除和修改的内容create trigger d2 on zg for insert,update,delete asselect * from deletedselect * from insertedselect * from zgdelete from zg where 班级=Nulldelete from zg where 姓名='张军'--建立触发器,如果zg表中没有此人的姓名,则不能在kc表中进行修改create trigger i2 on kc for insert,update asif(not exists(select 姓名from zg where 姓名=(select 姓名from inserted))) beginselect '不能修改数据'rollbackselect * from kcendelsebeginselect '修改成功'select * from kcendupdate kc set 选修人数=选修人数+100 where 姓名='张军'--建立触发器,更行zg时也更新kccreate trigger u2 on zg for update asselect * from deletedselect * from insertedupdate kc set 姓名=(select min(姓名) from inserted )where 姓名=(select min(姓名) from deleted)select * from zgselect * from kcupdate zg set 姓名='张晓军' where 姓名='张军'--建立触发器,如果加入的数>2000就不能插入并将默认值为500create trigger i3 on zg for insert asif((select 语文from inserted)>2000)beginselect '语文>2000不合适'update zg set 语文=500select * from zgrollbackendelseselect '修改成功'insert into zg(班级,姓名,学号,语文) values('小数','王五',20100637,2500)--建立触发器,不能删除总成绩最高的人create trigger d3 on zg for delete asif( select 总成绩from deleted) >= ( select max(总成绩)from zg)beginselect '删除的数为:'select * from deletedselect '不能删除成绩最高的一位'rollbackendelseselect '删除成功'select * from zgdelete from zg where 姓名='唐荣强'--建立触发器,英语增长不超过250%create trigger u3 on zg for update asif(select max(英语) from inserted )/(select min(英语) from deleted)>2.5beginselect * from deletedselect * from insertedselect '增长速度>250%不能修改'rollbackendelseselect '修改成功'select * from zgupdate zg set 英语=英语*3 where 姓名='杨杰'--通过触发器调用其他函数create proc p1 asselect * from zgcreate trigger u4 on zg for insert,delete,update asexec p1insert into zg(姓名,学号,班级)values('小王',20100638,'小语')--多个触发器运行顺序create trigger i5 on zg for insert,update asselect '你在插入数据'create trigger u5 on zg for update,insert asselect '你在修改数据'update zg set 姓名='张军' where 姓名='张晓军'--触发器create trigger j1 on kc for update,delete,insertasselect( '你正在修改数据');select * from deleteddelete from kc where 课程名称='计算机导论'insert into kc (学号,课程名称,课程代码,学分) values('1010','计算机导论','D032T',2) update kc set 学号=1007 where 学号=1006create trigger j2 on kc for deleteasdeclare @count varchar(20)select @count=str(@@rowcount)+'个学生被删除'select @countreturndelete from kc where 学分=1.5create trigger j3 on jun for insert,updateasif(select sum(年龄) from jun )>400beginselect '你们年龄大入要求:不予录取'rollbackendelsebeginselect '恭喜你,你被录取了'endinsert into jun (学号,爱好,年龄) values('111','编程',20)update zg set 总成绩=语文+数学+英语select * from zgcreate trigger y2 on zg for insert,updateasif( select sum(总成绩) from zg )>2000beginselect ' 你通过了考试,欢迎你晋级'rollbackendelseselect '很抱歉,你没有通过考试'select * from zgupdate zg set 语文=语文-50 select 语文from zg。
SQL实验报告(优秀范文5篇)第一篇:SQL实验报告实验四触发器实验(一)after触发器(1 1)在l l i neitem 表上定义一个 after 触发器, , 当修改列项目e e xtendedprice d i scountx tax 时, , 要把 s orders 表得to o tal pri ce e 一起修改, , 以保证数据一致性C RE ATE T RIGGERtrig _line ite m_ pr ice_ update on line it em fo rupda teaasbegin i f(UPDATE(ex tend edprice)o r UPDATE(tax)or UPD AT E(di scou nt))begin-—声明游标变量指向 inserted 表d eclarecursor_inserted c urs orrea d_onlyofor select order key,linenu mber,exte nd edpr ice, dis coun t, taxfromin ser ted—-息信找查取获量变明声ﻩ声明变量获取查找信息de clare order key in t, @linenumb erint,exte nd edpricereal,disscount real,tax real—-打开游标epoﻩen cursor_i ns ert ed—-标游取读ﻩ读取游标fe tchnextfrom cur sor _i ns erte dint o@o rderkey, @lin enumber,eext ende dprice, @di scount,t axwwhi le FETC H_S TATUS =0 nigebﻩnﻩ—-声明一个变量保存重新计算得新价格cedﻩﻩecl are @n ew_tota lpri cer ealﻩ select @n ew_t otal price= @ext en dedpr ice *(1 -@di scou nt)*(1 +@tax)—-用新得总价格变量更新 orders 表得 t ot alprice puﻩﻩupdate orde rsse t tot alpri ce= new_totalprice where or derkey=orde rkeyen hctefﻩext f ro m cur sor_i nser ted int o@order ke y, @li nenum ber, @ex tende dp rice,discoun t, @taxdneﻩllaedﻩlocate c ur sor_i nser te deend 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 ffor inse rta sbegin ——向指量变标游明声ﻩ声明游标变量指向ins erted 表de clarec ursor_inse rtedcursorread_ onl yﻩ for s ele ct orderkey,linenumbe r,ex te ndedp ric e,di scou nt,t axfrom insserte d--声明变量获取查找信息edﻩeclare @orde rk eyint, @lin enumber int,e xten dedp ricereal, @discountreal, @ta xreal -—ﻩ-打开游标open cursor_i ns erte d--ﻩ-读取游标fe tc hnex tf romcu rsor_ins ertedinto@o rd erkey,li nen umbeerr, ex ten ded pric e,dis count,tax ihwﻩile @@FE TCH_ STATU S=0 ebﻩegin-—格价新得算计新重存保量变个一明声ﻩﻩ声明一个变量保存重新计算得新价格cedﻩclare @n ew_tot alprice realcelesﻩct new _to ta lprice= @extend edp rice *(1-d is count)*(1+tax)—-新更量变格价总得新用ﻩﻩ用新得总价格变量更新orders 表得totalpri ceﻩ u pda teor ders s ett ota lpric e=total pric e+ @new_ tota lpr ice wwhhe re o rderke y=orderkeytefﻩetch next from cursor_ ins erte dinto o rder key, @l inen umber,e xtendeddp ric e, @disc ou nt, @t axeend 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 eon line item fo r de let eAAS begin--声明游标变量指向delet ed 表de clar e curso r_d eleted cursorre ad _on lyesrofﻩﻩele ctord erk ey,line numbe r,extende dp rice,discoun t, taxfromdel eted-ﻩ--声明变量获取查找信息declare ord erkey int,linenum be rint,extendedp ri ce r eal,discou nt real,ta xreal -—ﻩ-打开游标epoﻩen c urso r_ deleted——标游取读ﻩ读取游标efﻩetch next fr om cur sor_delete d in toorder ke y,l inenumb er,ext enddedprice, @di scoun t,taxwh ile@FETCH_STATUS=0begi n-—声明一个变量保存重新计算得新价格ﻩ declare @ne w_ to talpric erealﻩsselec t@new_t otalpr ice= @exte nde dpri ce*(1-@disco unt)*(1+ tax)-ﻩ-—用新得总价格变量更新orders 表得tot alp rice uﻩﻩupd ateorders set t otalpri ce=to talpr ice-@new _totalp rice wh er e order key= @ord erkeyfetchn ext f rom cursor_inse rt ed in to orderkey, @line numbe r,extendeeddprice, @d iscou nt,t ax dneﻩndddeal lo cat e cur sor_inse rted eend((4 4))验证 up d at e触发器—-查瞧号订单得 to ta a l pr i ceselec t*fro o mo o r ders whereorde r key=1 8 30;—-查瞧明细表得相关信息se l ect *f ro mlin ei i te e mw here or de e r key=183 0and l ine num m be e r =1;——验证 e update 触发器updat elineitem set t ax=tax+0、05whe re orderkey=1830;(二)i i n steadof触发器((1))在在 lineit em 表上定义一个ins tead o fupda te触发器, 当修改明细表中得数量量quan ti ty 时, 应先检查供应表par tsupp 得av ai lqty 就是否足够, 不足够则拒绝执行, 否则执行并修改相应数值以保证数据一致性于由于 in steadof 触发器更新某个表会使得该表上其她不满足更新列不能更新,因因用此逆向思维使用 a fter 触发器实现相同效果即先更新 qu antity, 再比较av ailqqtty, 如果满足更新数量, 就修改partsupp 得表得 a vailqty, 如果不满足, 则把lineitem得quantity 更新之后得数据重新修改回来ccreate trigge r trig_lin eit em_quanti ty_ upda teonli neit em f or upda teas begin if UPDATE(qu ant ity)bbegin ——向指别分量变标游明声ﻩ声明游标变量分别指向 i nserted 表与 d el eted 表edﻩdeclare c urso r_inser tedcur sorr ead_on lyfortcelesﻩﻩtorde rkey, partk ey,s uppkey,lin enum ber, quantit yfr om i nserteddecl arecursor_de leted c urs orrea d_ onl yf or select quantityfr 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_deleted int--打开游标ruc nepoﻩrsor_in sert ed poﻩopen cur sor_d eleted-—量变给赋值数标游取读ﻩ读取游标数值赋给变量fﻩfet chnext fromcu rsor_ insert edﻩiinto or de rk ey,pa rtkey, @suppk ey, @line nu mber, @qty _ins erte df et chnext fromcursor _d eletedint o q ty _de lete dwhi le fe tch_st atus=0 gebﻩegin--计算订单明细修改时, 订购数量得变化值inserte d表项-d elet ed表项ssel ect quantity_d if f_ li neit em= @q ty _in se rte d—@@q ty_deleteedﻩ--从parts upp 表获取ava ilq ty值, 注意partsupp 表得主键为(partk ey,suppkeey)tcelesﻩﻩt@quanti ty_p ar tsupp =av ailq ty fro m pa rtsu ppwﻩﻩwh er e suppkey= suppke yand part key= @par tk ey-—断判始开ﻩﻩ开始判断gebﻩbegi nfiﻩf quant ity _d iff_ lin eite m=0ﻩﻩ p rin t“ 更新得数量与原表中得值相同, 不需要更新”e ls eif @quantit y_d iff_lin eitem 〈=q uantity_partsuppﻩbe ginﻩpuﻩﻩpd ate partsupps et avail qty= availqty-@qua ntit y_d iff_li ne item ﻩpus erehwﻩppkey=suppkeyandp artkey= @par tke yﻩﻩ p rint “ 两个表都更新成功’ ﻩﻩﻩneﻩndels eigebﻩﻩinﻩuﻩﻩupdate li nei temsetquantit y=quantity+ @quanti ty_diff_linei temwhe re o rd erke y=@orde rke y and li nenu mber= @liine numberﻩp ri nt '更新失败”ﻩﻩendﻩ e nd efﻩﻩetch ne xtfr om c urso r_i nsertedi nto @ord erke y, @partkey,s upp key, @linenumb er, @qt y_ ins ert edf etch ne xt from curso r_de leted into @qt y_d elet ed dneﻩndd eallocat e cur sor _i nserte ddealloc at e cursor_de le ted eend eend(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_ insertonline item iinstead of inser t as bbegin-—声明游标变量指向 inserte d表d eclar e cur sor_inserte dcur sorrea d_ only f orsﻩﻩselect or derk ey,pa rtkey,sup pk ey, lin en umber,q uantityf rom ins er ted-—声明变量获取查找信息dec lare quantity int, @av ailq ty i nt, @suppkeyin t, @partkeyinntt, @o rderkey int, @linenu mber int-—标游开打ﻩ打开游标c nepoﻩcurs or_ins erted -ﻩ-—读取游标f etc hnext fro mcursor_insert edint o@orde rkey,partkey,@@ssuppkey, @linenumber,qu antity wh ile @@FETCH_S TATUS= 0igebﻩin--为变量赋值a tcelesﻩavailqtyy==av ai lqt y fr ompartsuppwﻩwhe re suppkey =@su ppk ey and part ke y= partke yﻩ if @quant ity 〈= @avail qt y-—如果可以更新bﻩbegin /ﻩﻩﻩ/*将将 insert ed 表中得记录插入到明细表*/ ﻩsniﻩserti nto l ineite m select *from i nsertedro=yekredroerehwﻩﻩrderk ey andlinenumb er = @linenumber */ﻩﻩ新更时同ﻩ*同时更新 part supp 表得数量*/ﻩﻩuupd ate pa rtsup pset a vailqty=availqty-@quanti tyﻩerehwﻩe sup pke y= @sup pkey and partkey=part key ppr int ’paarts upp 表有足够得货物可以满足 lin eitem 得quan tityy, 插入成功’endelsebeginﻩﻩ p rintt''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, @liinenumbe r, qu antity eﻩen ddeall ocat ecursor_ inserted end(3)在在 line ite m表上定义一个 inste ad of del ete 触发器,当当删除明细表中记录时时, 同时改变表供应表 partsupp 得ava il qtyy数值 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 ursorread _only forlesﻩﻩelect or derke y, par tkey,sup pkey, linenumbe r,quan tity fr om deleted -ﻩ--声明变量decl are s upp key i nt, par tke yint, @orde rkey int,linen umb erint, @quaant it y int—-标游开打ﻩ打开游标opencursor_deleted-—标游取读ﻩ读取游标ffetch next fr omcurs or _del et edin to @ord erkey , @partkey,s uppkeey, @lin en umber,q ua ntitywhi leFFET CH_ STATUS=0 igebﻩin*/*除删ﻩ*删除*/ﻩ de let e fromlineite m where linenu mber= line number and o rde rkey =ordder key*/新更时同ﻩ同时更新 pa rt supp 表得数量*/u pdateparts uppse tavailqt 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 omcurso r_del etedinto @ord er ke y,p ar tkey,@@suppkey, @lin enu mber,quanti ty neﻩnd edﻩea lloc ate cursor_ delete dend(4)验证 update 触发器--查瞧li neit em 得quan tit y select*fr omlin eit em whe re or derk ey =1830and li nenum ber=1;——查询partsupp 表得ava ilqt y se lect * from part supp w here suppk ey =(selectsupp key fr omlin eitem w here ord erkey=18 30)and partk ey=(s elec t part key from lin eite mwh er eorder key =18 30 a nd linenu mber=1)---更新数量过大——更新得值与原值相同---更新到+ + 2 00 数量, , 成功updateli neitem setquant ity=q uanti ty+ 200where order key=1830and lin en umber =1;--更新 +2 00成功后l ineite m得 quanti ty y 变化——更新+200 成功后par ts upp 表得a va ilqty 变化实验到此。
实验7 数据完整性实验一.实验目的本实验的目的是通过实验使学生加深对数据完整性的理解,学会创建和使用触发器。
二.相关知识SQL Server实现数据完整性的具体方法有4种:约束、缺省、规则和触发器。
其中约束和缺省在实验一中已接触过。
本实验重点学会创建和使用触发器。
触发器是实施复杂完整性的特殊类型的存储类型。
触发器不需要专门语句调用,当对它所保护数据进行修改时自动激活,以防止对数据进行不正确,未授权或不一致的修改。
创建触发器的语法为:CREA TE TRIGGER <触发器> ON <表名>[WITH ENCRYPTION]FOR {[DELETE][,][INSERT][,][UPDA TE]}[WITH APPEND][NOT FOR REPLICA TION]AS <SQL 语句组>其中:1)WITH ENCRYPTION 为加密选项。
2)DELETE 选项为创建DELETE 触发器。
DELETE触发器的作用是当对表执行DELETE操作时触发器被激活,并从指定表中删除元组,同时将删除的元组放入一个特殊的逻辑表(delete表)中。
触发器的动作可以检查delete表中的数据,以确定下一步该如何处理。
3)INSERT选项为创建INSERT触发器。
INSERT触发器在对指定表中执行插入数据操作时激活,激活后将插入表中的数据拷贝并送入一个特殊的逻辑表(inserted 表)中,触发器会根据INSERT表中的值决定如何处理。
4)UPDA TE选项为创建UPDA TE触发器。
UPDA TE触发器仅在对指定表中进行更新数据操作时激活。
UPDA TE触发器激活后把将要被更新的原数据移入delete表中再将要被更新后的新数据的备份送入insert表中,UPDA TE触发器对delete和inserted表进行检查,并决定如何处理。
5)NOT FOR REPLICA TION 选项说明当一个复制过程在修改一个触发器表时,与该表相关联的触发器不能被执行。
一、实验名称:触发器与存储过程二、实验目的:在SQL Server环境下熟悉如何用SQL编写触发器和存储过程。
三、实验内容:创建一个供应商-项目-零件数据库spj,由四个数据表构成:S(sno,sname,status,city)P(pno,pname,color,weight);J(jno,jname,city);Spj(sno,pno,jno,qty)用SQL实现如下数据库操作:1. 用SQL语句创建上述数据库,并满足一定的完整性约束(主键和外键)。
创建数据库SPJ,SQL语言如下:S(sno,sname,status,city):create table S(sno char(6) primary key,sname char(6),status int,city char(4),)P(pno,pname,color,weight);create table P(pno char(6) primary key,color char(2),weight int,)J(jno,jname,city);create table J(jno char(6) primary key,jname char(6),city char(6),)Spj(sno,pno,jno,qty)create table SPJ(sno char(6),pno char(6),jno char(6),qty int,primary key(sno,pno,jno),foreign key(sno) references S(sno),foreign key(pno) references P(pno),foreign key(jno) references J(jno),)2.用SQL修改spj表,删除三个外键的约束。
(1)删除SPJ中三个外键的约束:查询分析器——对象浏览器——RJXY68——SPJ——用户表——dbo.SPJ——约束——选中三个外键约束,右键单击删除(2)查询语句中编写如下语句创建并命名外键:alter table SPJadd constraint fs foreign key(sno) references S(sno)alter table SPJadd constraint fp foreign key(pno) references p(pno)alter table SPJadd constraint fj foreign key(jno) references J(jno)(3)删除已命名的外键:alter table SPJdrop constraint fsalter table SPJdrop constraint fpalter table SPJdrop constraint fj3. (1)创建触发器t1,修改零件表p表的零件号pno的时候自动修改供应情况表spj表的pno. create trigger t1 on Pfor updateasif update(pno)update SPJset SPJ.pno=inserted.pnofrom SPJ,inserted,deletedwhere SPJ.pno=deleted.pno(2)查询p表和spj表。
sql触发器实例触发器(Trigger)是数据库管理系统(DBMS)中的一种规则,它会在指定的数据库表发生特定事件(如插入、更新或删除)时自动执行。
下面我将为你展示一个简单的SQL 触发器示例。
示例场景假设我们有一个名为employees的表,用于存储员工信息,包括id, name, 和salary。
我们想创建一个触发器,确保每当有新员工添加时,他们的工资不能超过某个特定的值。
1.创建employees 表sqlCREATE TABLE employees (id INT PRIMARY KEY,name VARCHAR(100),salary DECIMAL(10, 2));2.创建触发器我们创建一个名为check_salary的触发器,当在employees表中插入新记录时,它会检查工资是否超过了5000。
如果超过了,触发器将中止插入操作。
sqlDELIMITER //CREATE TRIGGER check_salary BEFORE INSERT ON employeesFOR EACH ROWBEGINIF NEW.salary > 5000THENSIGNAL SQLSTATE'45000'SET MESSAGE_TEXT = 'Salary exceeds maximum limit';END IF;END;//DELIMITER ;在这个触发器中:•BEFORE INSERT ON employees指定了触发器是在向employees表插入新记录之前触发。
•FOR EACH ROW表示这个触发器会对插入操作中的每一行单独触发。
•IF NEW.salary > 5000检查即将插入的新记录的工资是否超过5000。
•SIGNAL SQLSTATE '45000'在工资超过限制时发出一个错误信号,中止插入操作。
3.测试触发器现在我们尝试插入一些记录来测试触发器的功能。
触发器——实验报告本次实验主要针对的是数据库的触发器,触发器可以在数据库中对指定的事件进行响应,可以在事件发生前或发生后对相关的SQL语句进行处理,从而实现对数据的限制、约束等相关操作。
本次实验的目标是通过实例了解什么是触发器,如何创建触发器以及触发器的应用。
一、实验环境本次实验使用MySQL数据库作为实验环境。
二、实验步骤1. 创建数据库和表结构首先,需要创建一个新的数据库,并新建一张表来进行触发器的测试。
这里,我们创建一个名为“students”的数据库和“grades”表。
表结构如下:CREATE TABLE grades(id int(11) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;2. 创建触发器接下来,我们要创建一个触发器来对数据进行限制。
比如,我们想对成绩的输入进行限制,限制只能输入0-100之间的分数。
创建触发器的语法如下:CREATE TRIGGER trigger_name{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_nameFOR EACH ROWBEGIN-- 触发器的处理END;以上语法中,trigger_name是触发器的名称,table_name是触发器所作用的表名,BEFORE或AFTER关键字表明触发器是在事件发生前还是发生后进行处理的,在本次实验中,我们使用BEFORE关键字,表示在事件发生前进行处理。
触发器可以应用在INSERT、UPDATE、DELETE事件上,我们用INSERT事件做例子,表示在插入数据之前实现相应的数据限制。
触发器中的处理代码可以是任何合法的SQL语句,其中可以使用NEW和OLD关键字来引用触发器作用的记录,NEW表示要插入或者修改的记录,OLD表示删除的记录。
实验7 数据完整性实验
一.实验目的
本实验的目的是通过实验使学生加深对数据完整性的理解,学会创建和使用触发器。
二.相关知识
SQL Server实现数据完整性的具体方法有4种:约束、缺省、规则和触发器。
其中约束和缺省在实验一中已接触过。
本实验重点学会创建和使用触发器。
触发器是实施复杂完整性的特殊类型的存储类型。
触发器不需要专门语句调用,当对它所保护数据进行修改时自动激活,以防止对数据进行不正确,未授权或不一致的修改。
创建触发器的语法为:
CREA TE TRIGGER <触发器> ON <表名>
[WITH ENCRYPTION]
FOR {[DELETE][,][INSERT][,][UPDA TE]}
[WITH APPEND]
[NOT FOR REPLICA TION]
AS <SQL 语句组>
其中:
1)WITH ENCRYPTION 为加密选项。
2)DELETE 选项为创建DELETE 触发器。
DELETE触发器的作用是当对表执行DELETE操作时触发器被激活,并从指定表中删除元组,同时将删除的元组放入一
个特殊的逻辑表(delete表)中。
触发器的动作可以检查delete表中的数据,以确
定下一步该如何处理。
3)INSERT选项为创建INSERT触发器。
INSERT触发器在对指定表中执行插入数据操作时激活,激活后将插入表中的数据拷贝并送入一个特殊的逻辑表(inserted 表)
中,触发器会根据INSERT表中的值决定如何处理。
4)UPDA TE选项为创建UPDA TE触发器。
UPDA TE触发器仅在对指定表中进行更新数据操作时激活。
UPDA TE触发器激活后把将要被更新的原数据移入delete表中再
将要被更新后的新数据的备份送入insert表中,UPDA TE触发器对delete和inserted
表进行检查,并决定如何处理。
5)NOT FOR REPLICA TION 选项说明当一个复制过程在修改一个触发器表时,与该表相关联的触发器不能被执行。
一个触发器只适用于一个表,每个表最多只能有三个触发器,它们分别是INSERT、UPDA TE和DELETE触发器。
触发器仅在实施数据完整性和处理业务规则时使用。
三.实验内容
本实验的内容为:
使用SQL设计触发器,通过SQL Server企业管理器定义它们。
具体完成下面例题:利用触发器来保证学生数据库中SC表的参照完整性,以维护其外码与参照表中的主码一致。
CREA TE TRIGGER SC_inserted ON SC
FOR INSERT
AS IF(SELECT COUNT(*)
FROM student,inserted,course
WHERE student.sno = inserted.sno AND o = o)=0 ROLLBACK TRANSACTION
四.实验步骤
1、在企业管理器中创建触发器
1)在企业管理器中,由服务器开始逐步扩展到触发器所属表的数据库(本例为学生课数据库),打开表文件夹,在表窗口中用鼠标右击触发器所属的表(本例为SC表)。
2)在弹出菜单上选择“所有任务”“管理触发器”项,则弹出如图所示的触发器属性对话框。
图触发器属性对话框
如果要新建触发器,在文本[T]的文本框中输入创建触发器的SQL语句(见实验内容),单击“检查语法”按钮进行语法的检查,检查无误后,单击确定按钮。
3)如果要修改触发器,则在名字弹出项中选择要修改的触发器名(本例为SC_inserted),然后在文本[T]的文本框中对已有的内容进行修改,检查无误后单击“确定”按钮。
4)如果要删除触发器,则在名字弹出项中选择要删除的触发器名(本例为SC_inserted),并检查文本[T]的文本框中的内容,看是否选得正确,最后单击“删除”按钮。
2、验证触发器
1)在企业管理器中,由服务器开始逐步扩展到触发器所属表的数据库(本例为学生选课数据库)。
此时,可在选课表中输入一条记录(学号:’99001’,课程号:’ 8’,成绩:88)。
显然,这条记录是不符合参照完整性的。
通过企业管理器输入时,会出现错误提示,违反了数据库的约束(如果你已经在SC和student以及SC和COURSE之间建立了外键约
束的参照完整性)。
2)如果你已经在SC和student以及SC和COURSE之间建立了外键约束的参照完整性),则删除之(分别选中STUDENT和COURSE表,打开”设计表”,选中主键修改)
3)打开SQL查询分析器,输入语句“INSERT INTO SC V ALUES(‘99001’,‘8’,88)”,查看执行结果。
(或打开SC表直接添加记录)
4)删除触发器(本例为SC_inserted),重复步骤3,观察结果。
[例2] 定义一个触发器,如果在学生表中插入记录,则提示“欢迎新同学”。
CREA TE TRIGGER welcome_student
ON student
AFTER INSERT
AS
PRINT '欢迎新同学!'
GO
如果进行插入操作如:
INSERT
INTO student(sno,sname)
V ALUES(‘95006’,‘王芳’)
则出现如图10所示结果:
(以下是删除触发器welcome_student)
USE XS
IF OBJECT_ID('welcome_student','TR') IS NOT NULL
DROP TRIGGER welcome_student;
GO
[例3]创建一个名为grade_warn 的触发器,当成绩大于100 时,就提示‘成绩不能大于100分’。
然后执行sp_helptrigger 列出表SC 中触发器的相关信息。
USE XS
IF OBJECT_ID('grade_warn','TR') IS NOT NULL
DROP TRIGGER grade_warn;
GO
CREA TE TRIGGER grade_warn
ON SC
FOR INSERT, UPDA TE
AS
declare @gg int
SELECT @gg=grade from inserted
if @gg>100
BEGIN
PRINT '成绩不能超过100分'
ROLLBACK
END
EXEC sp_helptrigger SC.
例如:
INSERT
INTO sc
V ALUES('95002','7',120);
观察执行结果
[例4] 当有人试图在student表中添加或更改数据时,向客户端显示一条消息。
IF OBJECT_ID('reminder','TR') IS NOT NULL
DROP TRIGGER reminder;
GO
CREA TE TRIGGER reminder
ON student
FOR INSERT, UPDA TE
AS RAISERROR (‘您没有权限修改此数据库’, 16, 10)
在STUDENT表中添加或修改一条记录,观察结果。