針對簡易圖書管理數據庫 BooksDB,完成下述功能。
1、不帶參數的存儲過程:創建一個存儲過程,查看所有讀者的姓名、可借本數、可借天數和已借 書本數。
2、帶輸入參數的存儲過程:創建一個存儲過程,實現借書功能;
3、帶輸入參數的存儲過程:創建一個存儲過程,實現還書功能;
4、帶輸入參數和輸出參數的存儲過程:創建一個存儲過程,輸入讀者的編號,輸出該讀者的姓名;
5、創建 DDL 觸發器,禁止用戶修改 BooksDB 數據庫中的表;
6、測試 AFTER 觸發器,理解 INSERTED 表和 DELETED 表的作用;
BooksDB中的幾個表:
1、不帶參數的存儲過程:
創建一個存儲過程,查看所有讀者的姓名、可借本數、可借天數和已借書本數。
create procedure usp_GetInfo as select rdName, canLendQty, canLendDay, rdBorrowQty from Reader, ReaderType where Reader.rdType = ReaderType.rdType 調用的時候: exec usp_GetInfo
2、帶輸入參數的存儲過程:
創建一個存儲過程,實現借書功能;
create procedure usp_BorrowBook @rdID char(9), @bkID char(9) as --先判斷有沒有這本書 if not exists(select * from Book where @bkID in (select bkID from Book)) begin raiserror('圖書館沒有該書,借閱失敗',10,1) return end --先判斷書是否在館 declare @bkState int select @bkState = bkState from Book where bkID = @bkID if @bkState = 0 begin raiserror('該書不在館,無法借閱',10,1) return end --在判斷該讀者的借書數量是否達到最大借書數量 declare @rdBorrowQty int , @canLendQty int select @rdBorrowQty = rdBorrowQty from Reader where rdID = @rdID select @canLendQty = canLendQty from ReaderType where rdType = (select rdType from Reader where rdID = @rdID) if @rdBorrowQty = @canLendQty begin raiserror('抱歉!你所借書的數量已經達到最大借書數量!借閱失敗!',10,1) return end --借書開始(1.修改書的狀態,2.修改改讀者的借書數量,3.向Borrow表中插入數據) update Book set bkState = 0 where bkID = @bkID update Reader set rdBorrowQty = rdBorrowQty + 1 where rdID = @rdID declare @canLendDay int select @canLendDay = canLendDay from ReaderType where rdType = (select rdType from Reader where rdID = @rdID) insert into Borrow values(@rdID,@bkID,GETDATE(),DATEADD(dd,@canLendDay,GETDATE()),null) --調用: exec usp_BorrowBook 'rd2017001','bk2017006'
exec usp_BorrowBook 'rd2017001','bk2017002' exec usp_BorrowBook 'rd2017002','bk2017002' --由於bk2017002已經被借出去了,所以會出現不在館的消息
3、帶輸入參數的存儲過程:
創建一個存儲過程,實現還書功能;
1 create procedure usp_ReturnBook 2 3 @rdID char(9), 4 5 @bkID char(9) 6 7 as 8 9 --還書(1.修改書的狀態,2.修改讀者的借書數量,3.在Borrow表中刪除這條借書紀錄) 10 11 update Book set bkState = 1 12 13 where bkID = @bkID 14 15 16 17 update Reader set rdBorrowQty = rdBorrowQty - 1 18 19 where rdType = (select rdType from Reader where rdID = @rdID) 20 21 22 23 delete from Borrow 24 25 where rdID = @rdID and bkID = @bkID 26 27 --調用 28 29 exec usp_ReturnBook 'rd2017001','bk2017002'
4、帶輸入參數和輸出參數的存儲過程:
創建一個存儲過程,輸入讀者的編號,輸出該讀者的姓名;
1 create procedure usp_GetName 2 3 @rdID char(9), 4 5 @rdName varchar(20) output 6 7 as 8 9 select @rdName = rdName from Reader 10 11 where rdID = @rdID 12 13 go 14 15 --調用 16 17 declare @rdName varchar(20) 18 19 exec usp_GetName 'rd2017001',@rdName output 20 21 select @rdName 姓名
5、創建 DDL 觸發器:
禁止用戶修改 BooksDB 數據庫中的表;、
create trigger tri_OnBookDB on database for ddl_table_events as print '無法在數據庫BookDB中創建,刪除,修改表!!' rollback --測試: create table Test (a int,b char(6)) drop table Borrow
6、測試 AFTER 觸發器,理解 INSERTED 表和 DELETED 表的作用;
Instead of觸發器:
一開始Borrow表中有這樣一條紀錄:
當創建Instead of 觸發器后:
create trigger tri_InsteadOf on Borrow instead of delete as select rdID, bkID from deleted --調用: delete from Borrow where rdID = 'rd2017001'
deleted表中會出現:
但是在Borrow表中這條紀錄並沒有被刪除。原因是觸發器中代替了所要執行的delete操作。
After 觸發器:
當向Borrow表中插入一條紀錄時候,應修改Reader表中的rdBorrowQty加1,而在Book表中修改相應的書的狀態為0。
1 alter trigger tri_Insert on Borrow after insert 2 3 as 4 5 --先要判斷該書在不在館 6 7 if not exists(select bkState from Book, inserted where Book.bkID = inserted.bkID) 8 9 begin 10 11 raiserror('該書不在館,無法插入!',10,1) 12 13 return 14 15 end 16 17 18 19 update Reader set rdBorrowQty = rdBorrowQty + 1 20 21 from Reader, inserted 22 23 where Reader.rdID = inserted.rdID 24 25 26 27 update Book set bkState = 0 28 29 from Book, inserted 30 31 where Book.bkID = inserted.bkID 32 33 34 35 --調用: 36 37 insert into Borrow values ('rd2017004','bk2017004',GETDATE(),30,null)
學習過程之中難免存在錯誤,望多多指出。