基于C语言+SQL Server2008实现(控制台)图书管理系统【100010024】

news2024/11/25 2:57:32

第1章 概述

1.1项目背景

随着科技的发展,尤其是计算机技术的迅猛发展,图书馆管理的问题从以往的人工管理,到现在的电脑化,系统化,是对图书馆管理方法的质的飞跃,这些技术不仅让图书馆管理变得更加方便、快捷、提高效率,对于用户来说也是有极大地帮助,系统化的图书馆让人们可以更方便的去找书,借书,还书等等一系列的功能,从而让图书馆实现了它的最大化价值。同时对于图书馆本身来说,通过系统,它可以提高图书管理的效率,也是图书馆的科学化、正规化管理的最好方法。所以,图书馆管理系统的研究开发,是一个特别值得去做的研究。

1.2编写目的

根据所学的数据库系统与程序设计的知识,针对图书管理系统,进行系统的需求分析,系统设计,数据库设计,编码,测试等,完成题目要求的功能,从而达到掌握开发一个小型数据库的目的。

1.3软件定义

本系统采用VC++6.0集成开发系统作为前台开发Windows窗体控制平台,采用SQLServer2008作为后台数据库的管理程序。

1.4开发环境

本系统适合运用于图书馆针对管理借阅者借阅图书。

下面简单介绍一下本系统的运行环境:

操作系统:Windows 7

数据库服务器:Microsoft SQL Server2008

编程工具:VC++6.0

绘图工具:Microsoft Visio 2010

第2章 需求分析

2.1问题陈述

2.1.1基本功能

图书管理系统,实现读者信息的借阅证号、姓名、年龄、职业等信息的管理;实现对图书信息的图书号、作者名、出版社、单价等信息点的管理,实现借阅信息的借阅证号、书号、时间等信息的管理,实现对逾期读者的管理

2.1.2数据库需要实现的功能

创建存储过程查询图书的数量;创建视图查询借阅逾期信息;创建触发器当增加、删除、修改读者信息或者图书信息时自动修改相应表的数据更新;建立数据库相关表之间的参照完整性约束。

2.1.3系统需要实现的功能

能实现以下主要功能

l 图书基本情况的录入、修改、删除等基本操作。

l 实现借书功能。

l 实现还书功能。

l 实现对所有购进图书的分类查询和分类统计。

l 能够按书名、作者等分类查询现有图书的数量。

l 对超期的情况能自动给出提示信息。

2.2业务处理流程

在这里插入图片描述

2.3数据流图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4数据字典

(1)图书管理员

简述:图书馆管理人员

组成:

Admin_idCHAR(7)
Admin_passwordCHAR(8)
Admin_nameNCHAR(5)

有关处理逻辑:系统管理权限的代表。

(2)读者

简述:图书馆借书看书的对象

组成:

Reader_idCHAR(7)
Reader_passwordCHAR(8)
Reader_nameNCHAR(5)
Reader_sexNCHAR(1)
Reader_ageTINYINT
Reader_CompanyNVARCHAR(20)
Reader_workNVARCHAR(20)

有关处理逻辑:图书馆读者权限的代表。

(3)图书信息表

简述:图书馆的书目

组成:

Book_idCHAR(6)
Book_nameNVARCHAR(20)
Book_writerNCHAR(5)
Book_publisherNVARCHAR(20)
Book_priceSMALLINT
Book_introductionNVARCHAR(100)
Book_typeNVARCHAR(20)

有关处理逻辑:图书馆其他实体对书目的操作。

(4)借阅信息表

简述:图书馆读者借书还书的记录

组成:

Reader_idCHAR(7)
Book_idCHAR(6)
Borrow_timeDATE

有关处理逻辑:图书馆的读者与图书之间的关系。

(5)图书馆采购员

简述:图书馆图书采购的工作人员

组成:

Shopper_idCHAR(7)
Shopper_nameNCHAR(5)
Shopper_sexNCHAR(1)
Shopper_ageTINYINT

有关处理逻辑:图书馆图书增添处理。

(6)图书采购信息表

简述:图书馆采购记录

组成:

Shopper_idCHAR(7)
Book_idCHAR(6)
Shop_timeDATE

有关处理逻辑:图书馆采购员与图书的关系。

(7)图书历史借阅表

简述:借书的历史的记录

组成:

Reader_idCHAR(7)
Book_idCHAR(6)
Borrow_timeDATE
Return_timeDATE

有关处理逻辑:图书馆的读者与图书之间的关系。

第3章 概念结构设计

3.1ER模型图

3.1.1实体ER图

在这里插入图片描述

3.1.2实体联系ER图

在这里插入图片描述

3.1.3完整ER模型图

在这里插入图片描述

第4章 逻辑结构设计

4.1关系模式

针对图书管理信息系统的需求,通过对借书流程的分析以及对ER图的分析,设计如下面的关系模式:

1)读者信息表,包括的数据项有:(借阅证号、密码、姓名、性别、年龄、所在单位、职业);

2)图书信息表,包括的数据项有:(书号、书名、作者、出版社、价格、内容简介、图书类型、库存);

3)借书信息表,包括的数据项有:(书号、借书时间、借阅证号);

4)还书信息表,包括的数据项有:(书号、还书时间、借阅证号);

5)管理员信息表,包括的数据项有:(管理员号、密码、姓名);

6)采购员信息表,包括的数据项有:(采购员号、姓名、性别、年龄);

7)采购信息表,包括的数据项有:(采购员号、书号、采购时间);

4.2规范化基本表

经过对初始关系模式的规范化处理,以下关系模式中不存在部分函数依赖和传递函数依赖,已经达到3NF。

1)读者信息表,包括的数据项有:(借阅证号、密码、姓名、性别、年龄、所在单位、职业);

2)图书信息表,包括的数据项有:(书号、书名、作者、出版社、价格、内容简介、图书类型);

3)借阅信息表,包括的数据项有:(书号、借阅证号、借书时间);

4)管理员信息表,包括的数据项有:(管理员号、密码、姓名);

5)采购员信息表,包括的数据项有:(采购员号、姓名、性别、年龄);

6)采购信息表,包括的数据项有:(采购员号、书号、采购时间);

7)借阅历史表,包括的数据项有:(书号、借阅证号、借书时间、还书时间);

模型中画双划线的是主码,并且借阅证号和书号是借阅关系的外码,采购员号和书号是采购关系的外码。书号、借阅证号、借书时间是借阅历史表的外码;

第5章 物理结构设计

5.1数据库结构

本系统数据库表的物理设计是通过SQL命令来创建数据库的,对表的数据项以及参照完整性约束进行了设计。如下是部分表创建命令:

go
use Library_342
--创建读者表
CREATE TABLE Reader (
  Reader_id    CHAR(7)  PRIMARY KEY,
  Reader_password  CHAR(8) NOT NULL,
  Reader_name  NCHAR(5) NOT NULL,
  Reader_sex   NCHAR(1) DEFAULT '男', 
  Reader_age   TINYINT,
  Reader_Company   NVARCHAR(20),
  Reader_work  NVARCHAR(20)
  )
--创建图书表
CREATE TABLE Book (
  Book_id      CHAR(6) 	  PRIMARY KEY,
  Book_name    NVARCHAR(20) NOT NULL,
  Book_writer  NCHAR(5),
  Book_publisher  NVARCHAR(20),
  Book_price   SMALLINT,
  Book_introduction    NVARCHAR(100),
  Book_type    NVARCHAR(20) NOT NULL,
  Book_num int not null,
  Book_allnum int not null
  )

5.2视图、索引、主关键字、权限

1)视图

---创建超期罚款信息视图
CREATE VIEW view_overdue(Reader_id,Reader_name,Book_name,Borrow_time,"超期","罚款")
AS
SELECT Reader.Reader_id,Reader.Reader_name,Book.Book_name,Borrow.Borrow_time,
	   DATEDIFF(DAY,Borrow.Borrow_time,CONVERT (date,GETDATE(),112))-30 ,
      (DATEDIFF(DAY,Borrow.Borrow_time,CONVERT (date,GETDATE(),112))-30)*0.05 
FROM Reader,Book,Borrow
WHERE Borrow.Book_id=Book.Book_id AND
      Reader.Reader_id=Borrow.Reader_id AND
      DATEDIFF(DAY,Borrow.Borrow_time,CONVERT (date,GETDATE(),112))>30 
--创建图书借阅数量视图
CREATE VIEW view_hotbook(Book_id,Book_name,"当前借阅数量","被借阅总次数")
AS
SELECT Book.Book_id,Book.Book_name,Book.Book_allnum-Book.Book_num,Book_allnum-Book.Book_num+COUNT(History.Book_id)
FROM Book,History
WHERE History.Book_id=Book.Book_id
GROUP BY Book.Book_id,Book_name,Book.Book_allnum-Book.Book_num 

2)索引

--在图书表上创建关于“图书类型”列的一个升序非聚集索引;
CREATE INDEX BookType ON Book(Book_type);

3)主关键字

详见数据库关系图;

4)权限

CREATE LOGIN login2 with password='abcd1234', default_database=Library_342
CREATE USER user2 FOR LOGIN login2 with default_schema=dbo
GRANT INSERT,SELECT,UPDATE,DELETE
ON Borrow
TO user2

5.3数据库关系图

在这里插入图片描述

5.4对数据库的操作

1)插入、修改、删除

这些基本操作可通过在数据库中直接操作,也可以在编写的图书管理系统中进行部分操作;

2)触发器

--创建TR_Borrow_insert_8_Booknum_exits触发器,每次最多能借8本书,判断图书库存,判断是否已借该书,并对图书库存进行更新
CREATE TRIGGER TR_Borrow_insert_8_Booknum_exits
ON Borrow AFTER insert
AS
IF (SELECT COUNT(Borrow.Reader_id) FROM Borrow,inserted
WHERE Borrow.Reader_id=inserted.Reader_id)>8
BEGIN 
     PRINT '最多只能借8本书! '	
     ROLLBACK
END
else IF (SELECT Book.Book_num FROM Book,inserted
WHERE Book.Book_id=inserted.Book_id)=0
BEGIN 
     PRINT '该图书库存不足! '	
     ROLLBACK
END
else
BEGIN 
     UPDATE Book
     SET Book_num=Book_num-1
     WHERE Book_id in (
		SELECT Book_id
		FROM inserted)
	 PRINT '图书库存已更新! '
END

--创建TR_Borrow_Delete_Booknum触发器,当删除借阅记录时,对图书库存进行更新并将借阅记录记录到借阅历史表中    
CREATE TRIGGER TR_Borrow_Delete_Booknum
ON Borrow AFTER delete
AS
BEGIN 
     UPDATE Book
     SET Book_num=Book_num+1
     WHERE Book_id in (
		SELECT Book_id
		FROM deleted)
	PRINT '图书库存已更新! '
	INSERT 
	INTO History(Reader_id,Book_id,Borrow_time)
	SELECT deleted.Reader_id,deleted.Book_id,deleted.Borrow_time
	FROM deleted
END

--创建TR_History_insert_Return_time触发器,当还书时还书时间不能比借书时间早      
CREATE TRIGGER TR_History_insert_Return_time
ON History AFTER INSERT
AS
IF (SELECT DATEDIFF(DAY,inserted.Return_time,inserted.Borrow_time) 
FROM inserted,History
WHERE History.Book_id=inserted.Book_id AND History.Reader_id=inserted.Reader_id) >0
BEGIN 
     PRINT '归还日期不能比借书日期早! '	
     ROLLBACK
END

--创建TR_Reader_Delete_Borrow触发器,当删除读者时,将该读者的借阅信息删除      
CREATE TRIGGER TR_Reader_Delete_Borrow
ON Reader  INSTEAD OF  delete
AS
BEGIN 
     DELETE
     FROM Borrow
     WHERE Borrow.Reader_id in(
     		SELECT Reader_id
     		FROM deleted)
	PRINT '该读者的借阅信息已删除! '
	DELETE
     FROM History
     WHERE History.Reader_id in(
     		SELECT Reader_id
     		FROM deleted)
	PRINT '该读者的借阅历史已删除! '
	DELETE
    FROM Reader
    WHERE Reader_id in(
     		SELECT Reader_id
     		FROM deleted)
    PRINT '该读者已删除! '
END

--创建TR_Book_Delete_Borrow_History触发器,当删除图书时,将该图书的借阅信息删除      
CREATE TRIGGER TR_Book_Delete_Borrow_History
ON Book INSTEAD OF delete
AS
BEGIN 
     DELETE
     FROM Borrow
     WHERE Borrow.Book_id in (
     		SELECT Book_id
     		FROM deleted)
	 PRINT '该图书的借阅信息已删除! '
     DELETE
     FROM History
     WHERE History.Book_id in (
     		SELECT Book_id
     		FROM deleted)
	 PRINT '该图书的被借阅历史已删除! '	 
	 DELETE
     FROM Book
     WHERE Book_id in(
     		SELECT Book_id
     		FROM deleted)
    PRINT '该图书已删除! '	 
END

3)存储过程

--存储过程查询某类图书的数量
CREATE  PROCEDURE  Book_Type_num
  @Book_type NVARCHAR(20)='自然科学'
AS
 SELECT Book_type, COUNT(Book.Book_id) '该类型的图书数量(一样的书只算一本)'
	FROM Book
    WHERE Book.Book_type = @Book_type 
    GROUP BY Book_type

--存储过程在Reader中插入一行数据,其各列数据均通过输入参数获得
CREATE PROC p_InsertReader
  @Reader_id    CHAR(7)  ,
  @Reader_password  CHAR(8),
  @Reader_name  NCHAR(5) ,
  @Reader_sex   NCHAR(1) , 
  @Reader_age   TINYINT,
  @Reader_Company   NVARCHAR(20),
  @Reader_work  NVARCHAR(20)
AS
 INSERT INTO Reader  
VALUES(@Reader_id,@Reader_password,@Reader_name,@Reader_sex,@Reader_age,@Reader_age,@Reader_work)

第6章 物理结构设计

6.1系统功能结构图

在这里插入图片描述

6.2****功能描述

1)用户登录

选择登录系统的用户类型,进行不同的功能使用;

2)查看图书信息

查看数据库中各种图书的信息,进行其他操作;

3)修改个人信息

对数据库中的个人信息进行更新;

4)还书

借阅信息的更新;

5)借书

插入借阅信息;

6)查看借阅记录

输出个人的借阅情况;

7)读者管理

对读者进行增、删、改操作;

8)图书管理

对图书进行增、删、改操作;

9)查看当前逾期信息

查看数据库中当前用户逾期罚款信息;

第7章 代码设计和界面设计

7.1代码设计

1)数据库的连接

本系统是通过VC嵌入式SQL来进行数据库的连接的,主要代码如下:

int CONNECT()
{
	EXEC SQL CONNECT TO MS-20170511WSQV.Library_342 USER abc.abcd; 
	if(sqlca->sqlcode==0)         
	{        
		printf("Connection to SQL Server established\n");  
	}
	else
	{ 
		printf("ERROR: Connection to SQL Server failed\n");
		return 1;       
	}  
}

int DISCONNECT()
{
	EXEC SQL DISCONNECT ALL;
	if(sqlca->sqlcode==0)         
	{        
		printf("DISConnection to SQL Server established\n");  
	}
	else
	{ 
		printf("ERROR: DISConnection to SQL Server failed\n");
		return 1;       
	} 
	return 1;
}

2)主函数main

系统程序的主函数设计,通过调用其他函数来实现管理图书系统;

int main()
{
	int select_num;
	int login_num;
	CONNECT();
	start_meun();
	while(1)
	{
		scanf("%d",&select_num);
		switch(select_num)
		{
		case 1:break;
		case 0://退出系统
			{
				system("cls");
				DISCONNECT();
				printf(" ------------------------------------------------------------\n");
				printf("       -=  感谢使用,再见! =-           \n");
				printf(" ------------------------------------------------------------\n");
				system("pause");
				exit(0);
				
			}
		default:printf("输入错误,请重新输入:");continue;
		}
		break;
	}
	while(1){
		login_meun();//登录界面函数
		login_num=login ();//登录处理
		switch(login_num)
		{
		case 1:admin();break;
		case 2:reader();break;
	}
	}
}

3)头文件

包含头文件、全局变量定义以及函数声明:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char LReader_num[20];
/**********函数声明**********/
int CONNECT();
int DISCONNECT();
void start_meun();     //初始界面
void login_meun();    //登录界面函数
int login (void);      //用户登录函数
void admin_menu();   //管理员功能界面函数
void reader_meun();   //读者功能界面函数
void admin();        //管理员函数
void reader();        //读者函数
void admin_reader();  //管理读者函数
void admin_book();   //管理图书函数
void allborrow();     //查看借阅情况函数
void overdue();      //超期罚款函数
void adminreader_menu();
void adminbook_menu();
void addreader();    //增加读者函数
void deletereader();  //删除读者函数
void updatereader();  //修改读者函数
void addbook();     //增加图书函数
void deletebook();   //删除图书函数
void updatebook();   //修改图书函数
void borrowbook();   //借书函数
void returnbook();    //还书函数
void searchpersonborrow();//查看个人借阅函数
void updateme();       //修改个人信息函数
void allbook();         //查看所有图书函数
void allreader();        //查看所有读者函数

4)用户登录函数

本系统用户分为两类,一类是读者,一类是管理员,分别拥有不一样的功能权限;区分两者的方法是链接数据库查询登录用户是否在数据库中的读者表中或者管理员表中;代码如下:

for(;;)
{
	printf("管理员账号:");
	scanf("%s",&admin_num);
	printf("登陆密码:");
	scanf("%s",&admin_pass);
	EXEC SQL SELECT Admin_id,Admin_password INTO :admin_num,:admin_pass
		FROM Admin
		WHERE Admin_id=:admin_num AND Admin_password=:admin_pass;
	if(sqlca->sqlcode!=0)
	{  
		printf("发生了错误%d\n",SQLCODE);
		count+=1;
		printf("帐号密码错误,请重新输入\n");
		if(count>=3)
		{
			system("cls");
			DISCONNECT();
			printf(" ------------------------------------------------------------\n");
			printf("         -=  感谢使用,再见! =-         \n");
			printf(" ------------------------------------------------------------\n");
			system("pause");
			exit(0);
		}
		continue;
	} 
	printf("登录成功!\n");
	break;
}

读者用户登录同上;

5)读着管理

管理员对于读者的管理操作,包括增删改,增加读者代码如下:

void addreader()
{
	char YN;
	printf("输入读者的ID:");
	scanf("%s",&LReader_id);
	printf("输入读者的密码:");
	scanf("%s",&LReader_password);
	printf("输入读者的名字:");
	scanf("%s",&LReader_name);
	printf("输入读者的性别:");
	scanf("%s",&LReader_sex);
	printf("输入读者的年龄:");
	scanf("%d",&LReader_age);
	printf("输入读者的所在单位:");
	scanf("%s",&LReader_Company);
	printf("输入读者的职业:");
	scanf("%s",&LReader_work);
	EXEC SQL INSERT INTO Reader  
		VALUES(:LReader_id,:LReader_password,:LReader_name,:LReader_sex,:LReader_age,:LReader_Company,:LReader_work);
	if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
	{
		printf("发生了错误%d\n",SQLCODE);
		return 1;   
	} 
	else
	{
		printf("增加成功!");
	}
	printf("是否需要打印(Y/N):");
	do{scanf("%s",&YN);}
	while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');
	if (YN == 'y' || YN == 'Y')
	{
		printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","Reader_password","LReader_name","Reader_sex","Reader_age","Reader_Company","Reader_work");
		printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",LReader_id,LReader_password,LReader_name,LReader_sex,LReader_age,LReader_Company,LReader_work);
		printf("打印完成!返回主菜单!\n");
		return 1;
	}
	printf("操作完成!返回主菜单!\n");
}

删除与修改函数与之类似;

6)输出所有读者

运用游标,链接数据库将表中所有信息打印出来;代码如下:

void allborrow()
{
	int  count=0;
	EXEC SQL DECLARE AX CURSOR FOR
		SELECT Reader_id,Book_id,Borrow_time
		FROM Borrow;
	EXEC SQL OPEN AX;
	for ( ; ; )
	{
		EXEC SQL FETCH AX INTO :LReader_id,:LBook_id,:LBorrow_time;
		if (sqlca->sqlcode!=0)
		{
			break;
		}
		if(count++ == 0)
		{
			printf("借阅情况<未还>:");
			printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");
		}
		printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);
	}
	EXEC SQL CLOSE AX;
	count=0;
	EXEC SQL DECLARE BX CURSOR FOR
		SELECT Reader_id,Book_id,Borrow_time,Return_time
		FROM History;
	EXEC SQL OPEN BX;
	for ( ; ; )
	{
		EXEC SQL FETCH BX INTO :LReader_id,:LBook_id,:LBorrow_time,:LReturn_time :LNull;
		if (sqlca->sqlcode!=0)
		{
			printf("打印完成!返回主菜单!\n");
			break;
		}
		if(count++ == 0)
		{
			printf("借阅历史<已还>:");
			printf("\n%-10s %-10s %-15s %-15s\n","Reader_id","Book_id","Borrow_time","Return_time");
		}
		printf("%-10s %-10s %-15s %-15s\n",LReader_id,LBook_id,LBorrow_time,LReturn_time);
	}
	EXEC SQL CLOSE BX;
}

7)图书管理

管理员对于图书的管理操作,包括增删改,删除图书代码如下:

void deletebook()
{
	char YN;
	printf("请输入你要删除的图书的ID:");
	scanf("%s",&LBook_id);
	EXEC SQL SELECT Book_id,Book_name,Book_writer,Book_publisher,Book_price,Book_introduction,Book_type,Book_num,Book_allnum INTO :LBook_id,:LBook_name,:LBook_writer:LNull,:LBook_publisher:LNull,:LBook_price:LNull,:LBook_introduction:LNull,:LBook_type,:LBook_num,:LBook_allnum
		FROM Book 
		WHERE Book_id=:LBook_id;
	if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
	{
		printf("发生了错误%d\n",SQLCODE);
		return 1;   
    } 
	printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Book_id","Book_name","Book_writer","Book_publisher","Book_price","Book_intro..","Book_type","Book_num","Book_allnum");
	printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\t%-10d\t%-10d\n",LBook_id,LBook_name,LBook_writer,LBook_publisher,LBook_price,LBook_introduction,LBook_type,LBook_num,LBook_allnum);
	printf("是否删除该图书(Y/N):");
	do{scanf("%s",&YN);}
	while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');
	if (YN == 'y' || YN == 'Y')
	{
		EXEC SQL DELETE
			FROM Book
			WHERE Book_id=:LBook_id;
		if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
		{
			printf("发生了错误%d\n",SQLCODE);
			return 1;   
		} 
		else
		{
			printf("删除成功!返回主菜单!\n");	
		}
	}
}

其他操作类似;

8)借阅信息函数

查看当前借阅的信息,连接数据库,输出已还借阅信息和未还的借阅信息,代码如下:

void allborrow()
{
	int  count=0;
	EXEC SQL DECLARE AX CURSOR FOR
		SELECT Reader_id,Book_id,Borrow_time
		FROM Borrow;
	EXEC SQL OPEN AX;
	for ( ; ; )
	{
		EXEC SQL FETCH AX INTO :LReader_id,:LBook_id,:LBorrow_time;
		if (sqlca->sqlcode!=0)
		{
			break;
		}
		if(count++ == 0)
		{
			printf("借阅情况<未还>:");
			printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");
		}
		printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);
	}
	EXEC SQL CLOSE AX;
	count=0;
	EXEC SQL DECLARE BX CURSOR FOR
		SELECT Reader_id,Book_id,Borrow_time,Return_time
		FROM History;
	EXEC SQL OPEN BX;
	for ( ; ; )
	{
		EXEC SQL FETCH BX INTO :LReader_id,:LBook_id,:LBorrow_time,:LReturn_time :LNull;
		if (sqlca->sqlcode!=0)
		{
			printf("打印完成!返回主菜单!\n");
			break;
		}
		if(count++ == 0)
		{
			printf("借阅历史<已还>:");
			printf("\n%-10s %-10s %-15s %-15s\n","Reader_id","Book_id","Borrow_time","Return_time");
		}
		printf("%-10s %-10s %-15s %-15s\n",LReader_id,LBook_id,LBorrow_time,LReturn_time);
	}
	EXEC SQL CLOSE BX;
}

9)逾期信息函数

连接数据库查看视图,输出超期罚款信息,代码如下:

void overdue()
{
	int  count=0;
	EXEC SQL DECLARE QX CURSOR FOR
		SELECT *
		FROM view_overdue;
	EXEC SQL OPEN QX;
	for ( ; ; )
	{
		EXEC SQL FETCH QX INTO
               :LReader_id,:LReader_name,:LBook_name,:LBorrow_time,:LOver_time,:LFine;
		if (sqlca->sqlcode!=0)
		{
			printf("发生了错误%d\n",SQLCODE);
			printf("打印完成!返回主菜单!\n");
			break;
		}
		if(count++ == 0)
		{
			printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","LReader_name","Book_id","Borrow_time","超期[天]","罚款[元]");
		}
		printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10f\n",LReader_id,LReader_name,LBook_name,LBorrow_time,LOver_time,LFine);
	}
	EXEC SQL CLOSE QX;
}

10)借书函数

读者对于图书的借阅操作,代码如下:

void borrowbook()
{	
	char YN;
	allbook();
	printf("请输入你要借阅的图书的ID:");
	scanf("%s",&LBook_id);
	EXEC SQL SELECT Book_id,Book_name,Book_writer,Book_publisher,Book_price,
                  Book_introduction,Book_type,Book_num,Book_allnum             
              INTO :LBook_id,:LBook_name,:LBook_writer:LLNull,:LBook_publisher:LLNull,
       :LBook_price:LLNull,:LBook_introduction:LLNull,:LBook_type,:LBook_num,:LBook_allnum
		FROM Book 
		WHERE Book_id=:LBook_id;
	if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
	{
		printf("发生了错误%d\n",SQLCODE);
		return 1;   
    } 
	printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Book_id","Book_name","Book_writer","Book_publisher","Book_price","Book_intro...","Book_type","Book_num","Book_allnum");
	printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\t%-10d\t%-10d\n",LBook_id,LBook_name,LBook_writer,LBook_publisher,LBook_price,LBook_introduction,LBook_type,LBook_num,LBook_allnum);
	printf("是否借阅该图书(Y/N):");
	do{scanf("%s",&YN);}
	while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');
	if (YN == 'y' || YN == 'Y')
	{
		printf("输入借阅时间(2017-XX-XX):");
		scanf("%s",&LBorrow_time);
		EXEC SQL INSERT 
			INTO Borrow(Reader_id,Book_id,Borrow_time)
			VALUES(:LReader_num,:LBook_id,:LBorrow_time);
		if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
		{
			printf("发生了错误%d\n",SQLCODE);
			return 1;   
		}
		printf("借阅成功!打印借阅信息!\n");
		EXEC SQL SELECT Reader_id,Book_id,Borrow_time INTO :LReader_id,:LBook_id,:LBorrow_time
			FROM Borrow
			WHERE Reader_id=:LReader_num AND Book_id=:LBook_id;
		if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
		{
			printf("发生了错误%d\n",SQLCODE);
			return 1;   
		}
		printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");
		printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);
		printf("操作完成!返回主菜单!\n");
	}
}

11)还书函数

读者对于图书的借阅操作,代码如下:

void returnbook()
{
	char YN;
	printf("请输入你要归还的图书的ID:");
	scanf("%s",&LBook_id);
	EXEC SQL SELECT Reader_id,Book_id,Borrow_time INTO :LReader_id,:LBook_id,:LBorrow_time
		FROM Borrow
		WHERE Reader_id=:LReader_num AND Book_id=:LBook_id;
	if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
	{
		printf("发生了错误%d\n",SQLCODE);
		return 1;   
	}
	printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");
	printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);
	printf("是否归还该图书(Y/N):");
	do{scanf("%s",&YN);}
	while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');
	if (YN == 'y' || YN == 'Y')
	{
		printf("输入归还时间(2017-XX-XX):");
		scanf("%s",&LReturn_time);
		EXEC SQL DELETE 
			FROM Borrow
			WHERE Reader_id=:LReader_num AND Book_id=:LBook_id;
		if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
		{
			printf("发生了错误%d\n",SQLCODE);
			return 1;   
		}
		EXEC SQL UPDATE History
			SET Return_time=:LReturn_time
			WHERE Reader_id=:LReader_num 
              AND Book_id=:LBook_id AND Borrow_time=:LBorrow_time;
		if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
		{
			printf("发生了错误%d\n",SQLCODE);
			return 1;   
		}
		printf("归还成功!打印信息!\n");
		EXEC SQL SELECT Reader_id,Book_id,Borrow_time
        ,Return_time INTO :LReader_id,:LBook_id,:LBorrow_time,:LReturn_time:LLNull
			FROM History
			WHERE Reader_id=:LReader_num 
             AND Book_id=:LBook_id AND Borrow_time=:LBorrow_time;
		if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
		{
			printf("发生了错误%d\n",SQLCODE);
			return 1;   
		}
	printf("\n%-10s %-10s %-15s %-15s\n","Reader_id","Book_id","Borrow_time","Return_time");
		printf("%-10s %-10s %-15s %-15s\n",LReader_id,LBook_id,LBorrow_time,LReturn_time);
		printf("操作完成!返回主菜单!\n");
	}
}

12)个人信息修改函数

读者对于自己的个人信息修改操作;代码如下:

void updateme()
{
	char YN;
	printf("你的个人信息:\n");
	EXEC SQL SELECT Reader_id,Reader_password,
         Reader_name,Reader_sex,Reader_age,Reader_Company,Reader_work INTO
        :LReader_id,:LReader_password,:LReader_name,:LReader_sex:LNull,
        :LReader_age:LNull,:LReader_Company:LNull,:LReader_work:LNull
		FROM Reader 
		WHERE Reader_id=:LReader_num;
	if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
	{
		printf("发生了错误%d\n",SQLCODE);
		return 1;   
    } 
	printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","Reader_password","LReader_name","Reader_sex","Reader_age","Reader_Company","Reader_work");
	printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",LReader_id,LReader_password,LReader_name,LReader_sex,LReader_age,LReader_Company,LReader_work);
	printf("是否修改(Y/N):");
	do{scanf("%s",&YN);}
	while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');
	if (YN == 'y' || YN == 'Y')
	{
		printf("输入新的密码:");
		scanf("%s",&LReader_password);
		printf("输入新的名字:");
		scanf("%s",&LReader_name);
		printf("输入新的性别:");
		scanf("%s",&LReader_sex);
		printf("输入新的年龄:");
		scanf("%d",&LReader_age);
		printf("输入新的所在单位:");
		scanf("%s",&LReader_Company);
		printf("输入新的职业:");
		scanf("%s",&LReader_work);
		EXEC SQL UPDATE Reader
			SET Reader_password=:LReader_password,Reader_name=:LReader_name,
               Reader_sex=:LReader_sex,Reader_age=:LReader_age,
               Reader_Company=:LReader_Company,Reader_work=:LReader_work
			WHERE Reader_id=:LReader_num;
		if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/
		{
			printf("发生了错误%d\n",SQLCODE);
			return 1;   
		} 
		else
		{
			printf("修改成功!查看修改结果!\n");
			EXEC SQL SELECT Reader_id,Reader_password,Reader_name,
                 Reader_sex,Reader_age,Reader_Company,Reader_work INTO 
                :LReader_id,:LReader_password,:LReader_name,:LReader_sex:LNull,
                :LReader_age:LNull,:LReader_Company:LNull,:LReader_work:LNull
				FROM Reader 
				WHERE Reader_id=:LReader_id;		printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","Reader_password","LReader_name","Reader_sex","Reader_age","Reader_Company","Reader_work");		printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",LReader_id,LReader_password,LReader_name,LReader_sex,LReader_age,LReader_Company,LReader_work);	
		}
		printf("操作完成!返回主菜单!\n");
		return 1;
	}
	printf("操作完成!返回主菜单!\n");	
}

主要功能代码如上,部分功能代码类似不依次举例,详见附录或者工程代码文件;

7.2界面设计

1)初始界面

在这里插入图片描述

2)登录界面

在这里插入图片描述

3)管理员功能界面

在这里插入图片描述

4)读者功能界面

在这里插入图片描述

5)图书管理界面

在这里插入图片描述

6)读者管理界面

在这里插入图片描述

♻️ 资源

在这里插入图片描述
大小: 2.17MB
➡️ 资源下载:https://download.csdn.net/download/s1t16/87248094

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/84346.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java EE初阶】创建线程的五种方式

文章目录1. 继承Tread,重写run()2. 实现Runnable接口&#xff0c;重写run()3. 使用匿名内部类&#xff0c;继承Thread4. 使用匿名内部类&#xff0c;实现Runnable5. 使用lambda表达式1. 继承Tread,重写run() 示例&#xff1a;pandas 是基于NumPy 的一种工具&#xff0c;该工具…

Kafka系列之:使用Kafka Manager实现leader分区平衡和broker节点上分区平衡

Kafka系列之:使用Kafka Manager实现leader分区平衡和broker节点上分区平衡 一、需求背景二、leader分区不平衡三、实现leader分区不平衡四、分区在节点不平衡五、实现分区在节点平衡一、需求背景 kafka节点扩容,分区不平衡现在需要leader分区平均分配在每个节点上同时分区副本…

基于Python+Django的项目申报审核平台系统

在各学校的教学过程中&#xff0c;django项目校内申报平台系统是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及。采用当前流行的B/S模式以及3层架构的设计思想通过Python技术来开发此系统的目的是建立一个配合网络环境的django高校学生项目校内申报平台&#xf…

OMV 5.6入坑指南(一)-openmediavalut 5.6安装

一、DIY NAS服务器 百度网盘里攒了一堆电影、电视剧&#xff0c;想下载到电脑里&#xff0c;买了个4T硬盘&#xff0c;然后发现不够用&#xff0c;然后又买了个还是不够用&#xff0c;然后自己又不想开电脑看电视电影&#xff0c;平时看电视电影都是在ipad上看的&#xff0c;台…

可视化管线

VTK中的可视化管线可用于读取或创建数据、分析和创建此数据的派生版本&#xff0c;并将数据写入磁盘或将其传递给渲染引擎进行显示。例如&#xff0c;您可以从磁盘读取一个三维数据体&#xff0c;对其进行处理以创建一组三角形&#xff0c;这些三角形通过该数据体表示一个等值曲…

全栈Jmeter接口测试(六):json断言元件,jmeter参数化实现

Jmeter(12)&#xff1a;json断言元件 json断言元件介绍&#xff1a; json断言元件与响应断言元件的功能类型&#xff0c;它只针对响应正文为json数据格 式的内容进行断言功能。 添加路径&#xff1a;右击http请求——断言——json断言 如下图展示&#xff1a; json断言元件字…

JAVA毕业设计——基于SpringBoot和thymeleaf的疫情信息管理系统 (源码+数据库)

github代码地址 https://github.com/ynwynw/CoronavirusManage-public 毕业设计所有选题地址 https://github.com/ynwynw/allProject 基于SpringBoot及thymeleaf搭建的疫情信息管理系统 (源码数据库)034 一、系统介绍 疫情信息管理系统应当具备两种对象&#xff0c;疫情管理…

【论文精读10】MVSNet系列论文详解-PatchmatchNet

PatchmatchNet&#xff0c;论文名为&#xff1a;PatchmatchNet: Learned Multi-View Patchmatch Stereo&#xff0c;本篇论文结合了较多过往文章的优化思想和类似模块&#xff0c;因此可能要更复杂一些。 本文是MVSNet系列的第10篇&#xff0c;建议看过【论文精读1】MVSNet系列…

【嵌入式linux】修改网口MAC地址

使用带有网络功能的设备时&#xff0c;如果局域网内可能会连接很多台设备&#xff0c;为了保证网络通信正常&#xff0c;要确保每台设备的硬件MAC地址都不相同&#xff0c;一般在批量生产的时候可以根据产品序列号(sn号)固化每台设备的MAC地址&#xff0c;防止出现MAC冲突的问题…

【云原生】Prometheus PromQL讲解与实战操作

文章目录一、PromQL介绍二、四种指标类型1&#xff09;counter&#xff08;计数器&#xff09;2&#xff09;gauge &#xff08;仪表类型&#xff09;3&#xff09;Histogram&#xff08;直方图类型&#xff09; 和 Summary&#xff08;摘要类型&#xff09;三、表达式四种数据…

8Manage PMO:多项目管理工作经验分享

在现代企业日常项目管理中&#xff0c;同时开展不同业务项目可说已经是“家常便饭”&#xff0c;项目经理手上开展多个项目&#xff0c;便需要兼顾各项目的人力资源、进度、问题、风险等。而在这种情况下&#xff0c;面对多项目管理该如何有效进行管理&#xff0c;有没有多项目…

换天空的几个方式技巧

1.魔棒工具 现将图层复制一层&#xff0c;用魔棒工具选中被复制的一层图中的天空将他删除。&#xff08;如果天空有一些未选中的位置&#xff0c;那么我们按住shift用鼠标去点击需要删除的位置他就会一起选中&#xff09; 这个就是我们删除之后的效果。 然后我们打开一张需要加…

体验了一下火爆全球的 ChatGPT,我震惊了

这几天&#xff0c;要说编程圈最热的话题&#xff0c;莫过于OpenAI的ChatGPT&#xff0c;写小说&#xff0c;写代码&#xff0c;找BUG&#xff0c;写论文&#xff0c;画漫画&#xff0c;谱曲……简直没有它干不了的事。 趁着下班时间&#xff0c;我也光速注册体验了一下&#…

VS Code 1.74 发布!

欢迎来到 VS Code 11月更新&#xff0c;此版本更新包括自定义资源管理器自动显示、隐藏活动栏和面板徽章、合并编辑器撤消/重做、管理不安全的存储库、Go to Definition on return、远程隧道等等&#xff0c;让我们一起看看完整更新吧&#xff01; 自定义资源管理器自动显示 引…

Linux Centos离线地图开发

相关教程&#xff1a; 1、如何搭建离线地图开发环境 视频教程 2、下载离线地图数据(金字塔瓦片数据&#xff09; 视频教程 3、下载离线地图地形数据库&#xff08;实现地表高低起伏&#xff09; 4、添加离线地图数据到本地服务器 &#xff08;含3D&#xff09; 视频…

NamedParameterJdbcTemplate —— SqlParameterSource实现具名参数查询

文章目录NamedParameterJdbcTemplate —— SqlParameterSource实现具名参数查询一、数据库准备二、java Bean实体类准备三、要执行的SQL语句四、定义业务接口service五、定义一个SqlParameterSource实现具名参数的实体类六、定义controller接口七、业务实现&#xff08;1&#…

基于java+springboot+mybatis+vue+mysql的疫苗接种管理系统

项目介绍 该系统的应用可以减少工作人员的劳动强度&#xff0c;提高工作效率与管理水平&#xff0c;具有很大的价值。它可以使疫苗接种管理系统上操作简单&#xff0c;成功率高&#xff0c;使网上疫苗接种管理系统的管理向一个更高层次前进。 本系统尝试使用springboot在网上…

动态规划及马尔可夫特性最佳调度策略(Matlab完整代码实现)

&#x1f4cb;&#x1f4cb;&#x1f4cb;本文目录如下&#xff1a;⛳️⛳️⛳️ 目录 1 概述 2 Matlab代码实现 3 写在最后 1 概述 动态规划是一种机器学习方法&#xff0c;它利用环境、计算资源和马尔可夫特性等知识来创建在环境中最佳执行的策略。有了这项强大的技术&#…

存储器层次结构

实际的软件开发过程中&#xff0c;常会遇到服务端请求响应时间长&#xff0c;吞吐率不够。 分析对应问题时&#xff0c;你肯定听过“主要瓶颈不在CPU&#xff0c;而在I/O”&#xff0c;存储很重要。 1 存储器的层次结构 存储器系统是通过各种不同方法和设备&#xff0c;一层层…

人肝HepG2细胞膜

人肝HepG2细胞膜 主要组成&#xff1a;细胞膜组分&#xff08;真核或原代细胞&#xff09;、高分子内核材料、功能因子 制备方法&#xff1a;薄膜包覆法 粒径控制&#xff1a;100-150 nm 平均电位&#xff1a;~ -20 mV 包载因子&#xff1a;影像分子、免疫分子等功能因子 包装…