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的罰款記錄 ,則測試成功

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