SQL图书馆部分功能

SQL图书馆部分功能

一、建表部分

管理员表,读者表,图书表,书籍表,借阅表,罚款表
建表前整理好各表主外键的关系,数据类型保持一致,最好画E-R图的草稿

​```c
--------------读者学生表READERS(卡号,姓名,性别,院系,邮箱,卡状态)假设学生卡号为7位,教职工卡号为5位
--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)  default  '正常'
);
			--sex列约束为男、女
alter table READERS
				 add constraint sex_check check(read_sex='男' or read_sex='女')
--读者表插入数据
INSERT   INTO  readers(read_no,read_name,read_sex,read_dept,Email) 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
----------------图书类别表catalog(ISBN,cata_name,cata_price,cata_writer,cata_publish,cata_total)
--DROP  TABLE CATALOG
--SELECT  *   FROM   CATALOG
CREATE   TABLE  CATALOG
(
ISBN   char(13)  primary key,
cata_name    char(10) ,
cata_price     decimal(10,2),
cata_writer    char(10),
cata_publish  char(10),
cata_total    int   default  0,
adm_no         char(10),
 foreign key  (adm_no)    references		ADM(adm_no)
)

GO;

-----------------图书表(图书ID,图书名称,状态,管理员工号)
--SELECT * FROM BOOKS
--DROP  TABLE BOOKS
--ALTER   TABLE  BOOKS
		--ADD  book_name  char(10)
CREATE TABLE BOOKS(
book_no      char(20)   primary key,
ISBN           char(13),
book_name  char(10),
book_status  char(10) default'可借',
foreign   key(ISBN)   references  CATALOG(ISBN)
);
--图书表中插入数据
--INSERT  INTO BOOKS(book_no,ISBN,adm_no,book_name) values('book001','isbn001','adm001','天生有罪');
GO
-----------------FINE(借书证号,图书编号,罚款金额)
--SELECT  *    FROM  FINE
CREATE    TABLE FINE(
read_no   char(10),
book_no  char(20),
obey_money   float,
constraint pk_fine  primary key(read_no,book_no),
foreign key (read_no)   references  READERS(read_no),
foreign key (book_no)   references  BOOKS(book_no),
);
GO
-----------------借阅表(卡号,图书号,借书时间,应还时间,还书时间,续借状态)
--SELECT * FROM BORROW
--select * from books
--drop  table borrow
CREATE TABLE  BORROW(
read_no   char(10),
book_no char(20),
borr_time    date   default convert(date,getdate()),
due_time     date   default  convert(date,dateadd(month,1,getdate())),
return_time  date,
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)
);
GO

二、图书录入功能

思路:

  1. 为catalog创建存储过程,输入ISBN,书名,价格,作者,出版社,册数,管理员工号
  2. 为catalog创建触发器,当向catalog插入数据时,自动向Books表中插入记录
    (1) Books中记录条数与册数相同,用while(@i<册数)循环实现;
    (2) 图书号book_no=concat(book,ISBN,@i)自动生成,ISBN,book_name从inserted表中获取,book_status默认为
    可借。

---------------------------------------------------------------------录入功能-------------------------------------------------------------------------------------
---------------------------------------------------------------------INSERT   CATALOG,BOOKS表自动插入BOOKS信息----------------------------------------------
GO;
---------Pro_InsertCatalog,图书管理员录入图书信息
CREATE     PROCEDURE		Pro_InsertCatalog     
@ISBN          char(13),
@cata_name   char(10),
@cata_price    decimal(10,2),
@cata_writer   char(10),
@cata_publish    char(10),
@cata_total         int,
@adm_no           char(10)
AS
BEGIN
INSERT     INTO    CATALOG  VALUES(@ISBN,@cata_name,@cata_price,@cata_writer,@cata_publish,@cata_total,@adm_no);
END

GO;

----------Tri_InsertCatalog,向catalog插入信息时,自动向BOOKS表插入信息
--图书表(图书ID,图书名称,状态,管理员工号)

CREATE   TRIGGER    Tri_InsertCatalog   ON  CATALOG  FOR   INSERT  AS
BEGIN 
-----当catalog中插入图书册数为n时,BOOKS表需插入n条记录
DECLARE     @cata_total    int   SET   @cata_total=(SELECT  cata_total   FROM  INSERTED)
DECLARE     @ISBN    char(13)   SET   @ISBN=(SELECT  ISBN  FROM  INSERTED)
DECLARE     @cata_name   char(10)  SET   @cata_name=(SELECT  cata_name   FROM  INSERTED)
DECLARE     @i   INT   SET  @i=1            --循环变量
			WHILE(@i<=@cata_total)
			BEGIN
					--自动生成BOOKS的book_no=book+ISBN+@i
					declare   @book_no    char(20)   set   @book_no=concat('book',@ISBN,convert(char(3),@i))
					INSERT  INTO   BOOKS(book_no,ISBN,book_name)  VALUES(@book_no,@ISBN,@cata_name)
					set  @i=@i+1
			END
END

GO;
-----------测试图书录入功能
delete    books
delete   catalog
select  *     from  catalog  go;
select   *   from    books;
exec  Pro_InsertCatalog 'isbn123456001','图书一号',48.50,'作者一号','出版社一号',5,'adm001'

三、借书功能

思路:

1.存储过程pro_insertBorrow,输入读者卡号、图书编号,自动将该记录插入到borrow表

(1)借阅时间取当前系统时间getdate(),
(2)应还时间为dateadd(month,1,getdate()),

(3)续借状态默认为未续借

2 触发器Tri_insertBorrow

(1) 从inserted表中提取信息,赋值给@read_no,@book_no
(2) 检查read_no对应的读者卡号是否挂失,挂失则rollback,不允许借书

(3) 检查book_no对应的书籍是否可借阅,已被借阅则rollback,不允许借书

(4) 卡号正常,书可借时,更新books表中书编号@book_no的状态为不可借


------------------------------------------------------借阅功能,insert   borrow时--------------------------------------
------------------------------------------------------将书状态改为不可借-----------------------------------------------
-------------------存储过程pro_InsertBorrow,输入read_no,ISBN,向BORROW中插入借阅记录

--DROP  PROCEDURE   pro_InsertBorrow   
CREATE  PROCEDURE   pro_InsertBorrow  @ReadNo  char(10),@BookNo  char(20) AS
BEGIN 
		INSERT INTO  BORROW(read_no,book_no)   VALUES(@ReadNo,@BookNo) 
END

--------------------触发器Tri_InsertBorrow,向Borrow中插入借阅记录时,自动改变书的状态
GO
--drop trigger  Tri_InsertBorrow 
CREATE  TRIGGER   Tri_InsertBorrow  ON  BORROW  FOR  INSERT  AS
BEGIN
------从insert 表中收集信息 
declare   @read_no     char(10)   set @read_no =(select read_no from   inserted)
declare   @book_no    char(20)   set @book_no =(select  book_no from   inserted)
print (@read_no)
print(@book_no)
	--读者卡挂失
	IF((select  card_status  from READERS  where   read_no =@read_no)='挂失')
		BEGIN 
			rollback
			print'此卡已挂失,不可借书'
		END
	--书已被借走,不可借阅
	IF((select  book_status  from  BOOKS  where   book_no =@book_no)='不可借' )
		BEGIN
			rollback
			print '此书已被接走,不可借阅'
		END
	IF((select  card_status  from READERS  where   read_no =@read_no)='正常'
			AND  (select  book_status  from  BOOKS  where   book_no =@book_no)='可借') 
		BEGIN
			print'借书成功'
			--更改BOOKS表中的book_status
			UPDATE  BOOKS
			SET  book_status='不可借'
			WHERE  book_no =@book_no 
		END
END

go;
-------------------------------------------测试借书功能Pro_InsertBorrow,Tri_InsertBorrow
select    *    from     BOOKS;
select    *    from     READERS;
select    *    from     BORROW;
--delete  borrow
UPDATE   READERS    SET   card_status='正常'     WHERE  read_no='read001'
UPDATE   BOOKS        SET   book_status='可借'    WHERE  book_no='bookisbn1234560011'
exec  pro_InsertBorrow  'read001','bookisbn1234560011'
go;

四、还书功能

思路:
1 存储过程Pro_updateBorrowReturn,输入book_no,read_no,retur_time,更新borrow表中的还书时间
2 触发器Tri_updateBorrowReturn
(1) 从inserted表中提取信息,赋值给@read_no,@book_no,@return_time,@due_tiem;
(2)比较@due_tme,@return_time,datediff(day,@due_time,@return_time)>0则 超期,将读者 卡号,图书编号,罚款金额(超期天数*0.1)插入罚款表
(3)更新books表中图书编号为@book_no书籍的book_stutus为可借

------------------------------------------存储过程还书Pro_UpdateBorrowReturn,输入还书日期,更新归还时间
CREATE    PROCEDURE    Pro_UpdateBorrowReturn  
@ReadNO    char(10),
@BookNo    char(20),
@ReturnTime   date AS
BEGIN
	UPDATE   BORROW
	SET   return_time=@ReturnTime 
	WHERE   read_no = @ReadNO  AND   book_no = @BookNo
END
go;
-----------------------触发器Tri_UpdateBorrowReturn 更新BORROW return_time时,将书改为可借,超期生成罚款单
--DROP  TRIGGER    Tri_UpdateBorrowReturn  
CREATE   TRIGGER    Tri_UpdateBorrowReturn  ON  BORROW    FOR   UPDATE     AS
BEGIN 
declare   @ReadNo    char(10)    set   @ReadNo =(select  read_no   from   inserted)
declare   @BookNo   char(20)   set   @BookNo=(select  book_no   from   inserted)
declare   @ReturnTime  date     set   @ReturnTime=(select  return_time   from   inserted)
declare   @DueTime     date      set   @DueTime=(select  due_time   from   inserted)
		--列级触发器
			IF  UPDATE(return_time)
			BEGIN 
				--将书改为可借
				UPDATE    BOOKS     SET    book_status ='可借'    WHERE   book_no=@BookNo
				--判断是否超期
						IF   (datediff(day,@DueTime,@ReturnTime)>0)
						BEGIN
							print '借书超期,超期一天罚款0.1元'
							declare   @dalay_day  int    set    @dalay_day=abs(datediff(day,@DueTime,@ReturnTime))
							declare  @money   float     set   @money=0.1*@dalay_day
							INSERT    INTO   FINE   VALUES (@ReadNo,@BookNo,@money);
						END
			END	
END

go;
------------------------------------------------------测试还书功能,还书更新return_time,超期生成罚款单
select    *    from     BOOKS;
select    *    from     READERS;
select    *    from     BORROW;
select    *    from    FINE;
--delete  borrow
--借书部分
UPDATE   READERS    SET   card_status='正常'    WHERE  read_no='read001'
UPDATE   BOOKS    SET   book_status='可借'    WHERE  book_no='bookisbn123456001'
exec  pro_InsertBorrow  'read001','bookisbn1234560011'
--还书部分
exec   Pro_UpdateBorrowReturn  'read001','bookisbn1234560011','2020-05-29'

go;

五、续借功能

思路:
总结:图书的是否被借阅过要从deleted的旧表中查看,inserted表肯定是显示为续借的。
1 存储过程Pro_updateBorrowDue 输入读者卡号,图书编号,实现book_status更新
2 触发器Tri__updateBorrowDue
(1) 从deleted表收集图书原来的book_status,read_no,book_no
(2) 如果book_status显示为已续借,则该读者已续借过一次,不可再次续借.
(3) 检查read_no字段的长度,如果为7位长,则为学生,可续借1个月,更新books表的due_time=dateadd(month,1,@due_time)
(4) 检查read_no字段的长度,如果为6位长,则为学生,可续借3个月,更新books表的due_time=dateadd(month,3,@due_time)


----------------------------------------------------续借存储过程Pro_UpdateBorrowDue,教职工卡考位8位,可续借三个月,学生卡号为10位,可续借一个月
--DROP  PROCEDURE   Pro_UpdateBorrowDue 
CREATE  PROCEDURE   Pro_UpdateBorrowDue   
 @ReadNo  char(10),
 @BookNo char(20) AS
BEGIN
			UPDATE   BORROW  SET    renew_status = '已续借'   WHERE   read_no = @ReadNo  AND   book_no = @BookNo
END

GO;
---------------------------------------------------触发器续借Tri_UpdateBorrowDue,已续借不可续借,卡号7位可续借1个月,卡号6位可续借3个月
--DROP  TRIGGER    Tri_UpdateBorrowDue
CREATE   TRIGGER    Tri_UpdateBorrowDue    ON  BORROW   FOR    UPDATE    AS
BEGIN
declare   @ReadNo     char(10)        set   @ReadNo=(select   read_no  from  inserted) 
declare   @BookNo     char(20)        set   @BookNo=(select  book_no  from  inserted) 
declare   @RenewStatus   char(10)    set   @RenewStatus=(select   renew_status from  deleted) -------------查看deleted表中续借状态
declare   @DueTime    date              set   @DueTime=(select  due_time   from   inserted)
IF   UPDATE(renew_status)
BEGIN
		-----判断是否已续借
		IF(@RenewStatus='已续借')
		BEGIN
					rollback
					print'此书已续借,不可再次续借'
		END
		IF(@RenewStatus='未续借')
		BEGIN
					print'此书未续借,可续借'
					-----判断是教师还是学生
						print(len(@ReadNO))
						IF(LEN(@ReadNo)=7)-----学生
						BEGIN 
								---更新due_tim,renew_status
								UPDATE   BORROW     SET    due_time=CONVERT(date,dateadd(month,1,@DueTime) ) WHERE    book_no =@BookNo AND read_no =@ReadNo
								UPDATE  BORROW      SET  renew_status='已续借'     WHERE    book_no =@BookNo AND read_no =@ReadNo
								print'续借成功,已延期一个月'
						END
						IF(LEN(@ReadNo)=6)-----教师
						BEGIN 
								---更新due_time, renew_status
								UPDATE   BORROW     SET    due_time=CONVERT(date,dateadd(month,3,@DueTime) ) where   book_no =@BookNo AND read_no =@ReadNo
								UPDATE  BORROW    SET  renew_status='已续借'     WHERE    book_no =@BookNo AND read_no =@ReadNo
								print'续借成功,已延期三个月'
						END				
		END
END
END


GO;
---------------------------------------------------测试续借功能
select    *    from     BOOKS;
select    *    from     READERS;
select    *    from     BORROW;
select    *    from    FINE;
--delete  borrow
--delete  fine
--借书部分
UPDATE   READERS    SET   card_status='正常'    WHERE  read_no='read001'
UPDATE   BOOKS    SET   book_status='可借'    WHERE  book_no='bookisbn1234560011'
exec  pro_InsertBorrow  'read001','bookisbn1234560011'
--续借部分
exec    Pro_UpdateBorrowDue  'read001' ,'bookisbn1234560011'
-------------------------------------------教师借书
--借书部分
INSERT   INTO    READERS(read_no,read_name,read_sex,read_dept,Email)   VALUES('Tea001','教师一号','男','计算机系','Email002')
UPDATE   READERS    SET   card_status='正常'    WHERE  read_no='Tea001'
UPDATE   BOOKS    SET   book_status='可借'    WHERE  book_no='bookisbn1234560012'
exec  pro_InsertBorrow  'Tea001','bookisbn1234560012'
--续借部分
exec    Pro_UpdateBorrowDue  'Tea001' ,'bookisbn1234560012'
GO;

六、查看一个学生的借阅的图书

存储过程 Pro_checkReaderBooks
(1) 输入读者卡号,返回读者借阅的图书名称和图书编号
(2) 将borrow和reader表自然连接,即读者卡号相同的连接,将卡号为输入卡号的元组筛选出来,投影出图书编号和图书名称两列
(3) SQL:select book_name,book_no
From reader inner jion borrow on reader.read_no =borrow.book_no
Where read_no = @Read_no

----------------------------------------------------------------查询某读者借阅的所有图书------------------------------------------------------------------------------------
-----------------------------------------------------------------Pro_checkReaderBooks
CREATE      PROCEDURE   Pro_checkReaderBooks
@read_no  char(10),
@book_no   char(20)  output,
@book_name   char(10)   output
AS
BEGIN
set   @book_no=
							(SELECT   borrow.book_no
							FROM    BORROW,BOOKS
							WHERE    borrow.book_no=books.book_no
							AND read_no =@read_no)
set   @book_name=
								(SELECT   books.book_name
								FROM    BORROW,BOOKS
								WHERE    borrow.book_no=books.book_no
								AND read_no =@read_no)
END

go;
---------------测试
declare  @BookNo  char(20)
declare  @BookName    char(10)
exec    Pro_checkReaderBooks 'read001', @BookNo  output, @BookName output
print @BookNo
print @BookName

七、总结


1.连接字符串可以用concat(),以此自动生成book_no=concat(‘book’+’isbn’+@i)

当设值的大小大于isbn实际的大小时,concat连接会有空格

2 identity(初始值,步长)只能用于建表或修改表时的某一列,不能用于和isbn+identity(1,1)生成book_no

3.聚合函数的使用

select 的列名必须在group by 【列1】 中,因为group之后,【列1】值相同的记录归纳为一组了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章