SQL触发器综合习题

SQL触发器综合习题

在这里插入图片描述
总结

1 每写完一段代码时,后面加一个go,方便后面的分段执行

2 在创建表的代码前备注好 select * from 表名,delete 、drop 以便调试,创建触发器前也备注好删除触发器的SQL代码,触发器创建完成后,要写go

3 最好不要在建表后,马上插入数据,而是在测试触发器时,再给出相应的代码,测试完一个功能后,删除数据。

保证每一次测试的环境都是我们现场给出的。

4 where 子句中某一列中的值写错了,不会报错

5 if 语句中同时满足两个条件用and 满足二者之一 用or

建表、插入数据、建立触发器、测试触发器

--读者表(卡号,姓名,性别,院系,邮箱,卡状态)
--DROP  TABLE  READERS
--DELETE  READERS
--SELECT * FROM READERS
CREATE  TABLE  READERS (
read_no   char(10)  primary key,
read_name   char(10) not null,
read_sex      char(2) ,
read_dept    char(10),
Email          char(10),
card_status  char(10)
);
			--sex列约束为男、女
alter table READERS
				 add constraint sex_check check(read_sex='男' or read_sex='女')
--读者表插入数据
INSERT   INTO  readers   values('read001','一号选手','男','计算机系','email001','正常');
GO 
--创建管理员表(工号,姓名,联系方式)
--drop  adm
--SELECT * FROM ADM
CREATE  TABLE ADM(
adm_no  char(10) primary key,
adm_name  char(10) ,
adm_number   char(10)
);
--插入数据
INSERT INTO ADM VALUES ('adm001','管理员一号','number001');
GO
--创建图书表(图书ID,图书名称,状态)
--SELECT * FROM BOOKS
--DROP  TABLE BOOKS
CREATE TABLE BOOKS(
book_no   char(10)   primary key,
ISBN   char(10)  not null,
b_status  char(10),
adm_no  char(10),
foreign key  (adm_no)  references ADM(adm_no)
);
--图书表中插入数据
INSERT  INTO BOOKS values('book001','isbn001','可借','adm001');
GO
--FINE(借书证号,图书编号,罚款金额)
CREATE  TABLE FINE(
read_no   char(10),
book_no  char(10),
obey_money   float,
constraint pk_fine  primary key(read_no,book_no)
);
GO
--创建借阅表(卡号,图书号,借书时间,应还时间,还书时间,续借状态)
--SELECT * FROM BORROW
--select * from books
--drop table borrow
CREATE TABLE  BORROW(
read_no   char(10),
book_no char(10),
borr_time     char(20)    default  convert(char(20),getdate()),
due_time      char(20)    default  convert(char(20),dateadd(month,1,getdate())),
return_time  char(20)    default   'null',--默认空值怎么写
renew_status   char(10)  default '未续借',
 CONSTRAINT pk_borr  PRIMARY KEY (read_no,book_no),
 foreign key  (read_no)    references		READERS(read_no),
 foreign key  (book_no)    references		BOOKS(book_no)
);

--备份borrow表
--SELECT * FROM BORR_BAK
SELECT  *  INTO   BORR_BAK   FROM  BORROW
--删除borrow表中的所有记录
DELETE  BORROW
---------------------------------------------触发器Tri_InsertBorrow-----------------------------------
go
--创建触发器 Tri_InsertBorrow
--(1)检查借阅证号,挂失则显示‘借书证已挂失’rollback
--(2)检查图书是否可解,不可借则显示‘图书不可借阅’rollback
--(3)两者都不满足,则可以插入借阅表,更新books表中的借阅状态
--DROP TRIGGER Tri_InsertBorrow
CREATE  TRIGGER  Tri_InsertBorrow    ON  BORROW  FOR  INSERT AS
BEGIN
			IF  (select   card_status  
				 from  inserted   as  I inner  join   readers  as R
			     on   I.read_no = R.read_no)='挂失'
				 BEGIN
				 print  '该借书证已挂失,不可借书'
				 rollback
				 END
			IF   (select  b_status  
			    from  inserted  as I  inner join  books  as B  
			    on  I.book_no = B.book_no)='不可借'
				BEGIN
				print '图书已被借,不可借阅'
				rollback
				END
			IF  (select   card_status  
				 from  inserted   as  I inner  join   readers  as R
			     on   I.read_no = R.read_no)='正常'
			     AND  (select  b_status  
			    from  inserted  as I  inner join  books  as B  
			    on  I.book_no = B.book_no)= '可借'
			BEGIN
			print '借书成功'
			UPDATE  BOOKS
			set    b_status='不可借'
			from books as B  inner join inserted as I
			on B.book_no=I.book_no
			END
END

go
--测试Tri_InsertBorrow

--DELETE  BORROW
--SELECT  *  FROM  BORROW
--SELECT  *  FROM  BOOKS
--SELECT * FROM  READERS

--TEXT1  卡号正常,图书可借
update  readers
set   card_status='正常'
where   read_no ='read001'
update  books
set  b_status = '可借'
where  book_no='book001'
INSERT INTO BORROW(read_no,book_no) VALUES('read001','book001');
delete borrow
--TEXT2  卡号正常,图书不可借
update  readers
set   card_status='正常'
where   read_no ='read001'
update  books
set  b_status = '不可借'
where  book_no='book001'
INSERT INTO BORROW(read_no,book_no) VALUES('read001','book001');
delete  BORROW
--TEXT3  卡号挂失,图书可借
update  readers
set   card_status='挂失'
where   read_no ='read001'
select  *  from readers
update  books
set  b_status = '可借'
where  book_no='book001'
INSERT INTO BORROW(read_no,book_no) VALUES('read001','book001');
delete borrow

--创建触发器Tri_UpdateBorrow
--修改borrow(return_time)时,将books(b_status)改为可借
--判断是否超期 datediff(day,getdate(),convert(datetime,due_time))>0
--超期将read_no ,book_no,money追加到罚款单fine表中。
--疑惑:将return_time 设置为datetime数据类型,怎么设置为空呢?不给值就好!
go
---------------------------触发器Tri_UpdateBorrow-----------------------------------------------------
--drop  TRIGGER Tri_UpdateBorrow
CREATE   TRIGGER Tri_UpdateBorrow  ON  BORROW  FOR UPDATE  AS
BEGIN 
			--将books改为可借
			IF  UPDATE(return_time)
				BEGIN
				UPDATE  BOOKS
				set   b_status='可借'
				from   books  as  B  inner join  inserted  as  I
				on  B.book_no = I.book_no		
				END
			--处理超期
			declare   @dueTime  date  --存放应还书时间,borrow中就有应还时间
			set         @dueTime=convert(date,(select  due_time  from inserted ))
			declare   @returnTime  date --存放还书时间 ,borrow表 即inserted表
			set         @returnTime=(select  return_time  from inserted)
			declare   @delay_day  int   --存放超期时间
			set         @delay_day = datediff(day,@returnTime,@dueTime)
			print    @delay_day
			IF         @delay_day<0
			BEGIN 
					print '@delay_day'
					--将读者卡号,书籍编号,罚款金额写入fine表,设超期一天,罚款金额为0.1
					declare    @readNo  char(10)   set  @readNo=( select read_no  from  inserted)
					declare    @bookNo  char(10)   set  @bookNo=( select book_no  from  inserted)
					INSERT INTO FINE  values (@readNo,@bookNo,abs(@delay_day*0.1)); 
					print  '已插入罚款单'
			END
END
go

--测试 Tri_updateBorrow
--select * from borrow
--select  *  from books
--select *  from  fine

--删除掉原有数据,重新插入,方便测试
delete  fine
delete  borrow
delete   books
INSERT  INTO BOOKS values('book001','isbn001','可借','adm001');
INSERT INTO BORROW(read_no,book_no) VALUES('read001','book001');--触发 Tri_insertBorrow,b_status变为不可借

--text1
update  borrow
set  return_time='2020-6-9'
where  read_no='read001'
AND  book_no = 'book001' 

--如books表book001书籍状态改为可借
--在fine表中有read001的罚款记录 ,则测试成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章