基于C语言+SQL Server2008实现(控制台)图书管理系统
第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_id | CHAR(7) |
---|---|
Admin_password | CHAR(8) |
Admin_name | NCHAR(5) |
有关处理逻辑:系统管理权限的代表。
(2)读者
简述:图书馆借书看书的对象
组成:
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) |
有关处理逻辑:图书馆读者权限的代表。
(3)图书信息表
简述:图书馆的书目
组成:
Book_id | CHAR(6) |
---|---|
Book_name | NVARCHAR(20) |
Book_writer | NCHAR(5) |
Book_publisher | NVARCHAR(20) |
Book_price | SMALLINT |
Book_introduction | NVARCHAR(100) |
Book_type | NVARCHAR(20) |
有关处理逻辑:图书馆其他实体对书目的操作。
(4)借阅信息表
简述:图书馆读者借书还书的记录
组成:
Reader_id | CHAR(7) |
---|---|
Book_id | CHAR(6) |
Borrow_time | DATE |
有关处理逻辑:图书馆的读者与图书之间的关系。
(5)图书馆采购员
简述:图书馆图书采购的工作人员
组成:
Shopper_id | CHAR(7) |
---|---|
Shopper_name | NCHAR(5) |
Shopper_sex | NCHAR(1) |
Shopper_age | TINYINT |
有关处理逻辑:图书馆图书增添处理。
(6)图书采购信息表
简述:图书馆采购记录
组成:
Shopper_id | CHAR(7) |
---|---|
Book_id | CHAR(6) |
Shop_time | DATE |
有关处理逻辑:图书馆采购员与图书的关系。
(7)图书历史借阅表
简述:借书的历史的记录
组成:
Reader_id | CHAR(7) |
---|---|
Book_id | CHAR(6) |
Borrow_time | DATE |
Return_time | DATE |
有关处理逻辑:图书馆的读者与图书之间的关系。
第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 ANDReader.Reader_id=Borrow.Reader_id ANDDATEDIFF(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 BookSET Book_num=Book_num-1WHERE Book_id in (SELECT Book_idFROM inserted)PRINT '图书库存已更新! '
END--创建TR_Borrow_Delete_Booknum触发器,当删除借阅记录时,对图书库存进行更新并将借阅记录记录到借阅历史表中
CREATE TRIGGER TR_Borrow_Delete_Booknum
ON Borrow AFTER delete
AS
BEGIN UPDATE BookSET Book_num=Book_num+1WHERE Book_id in (SELECT Book_idFROM deleted)PRINT '图书库存已更新! 'INSERT INTO History(Reader_id,Book_id,Borrow_time)SELECT deleted.Reader_id,deleted.Book_id,deleted.Borrow_timeFROM 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 DELETEFROM BorrowWHERE Borrow.Reader_id in(SELECT Reader_idFROM deleted)PRINT '该读者的借阅信息已删除! 'DELETEFROM HistoryWHERE History.Reader_id in(SELECT Reader_idFROM deleted)PRINT '该读者的借阅历史已删除! 'DELETEFROM ReaderWHERE Reader_id in(SELECT Reader_idFROM deleted)PRINT '该读者已删除! '
END--创建TR_Book_Delete_Borrow_History触发器,当删除图书时,将该图书的借阅信息删除
CREATE TRIGGER TR_Book_Delete_Borrow_History
ON Book INSTEAD OF delete
AS
BEGIN DELETEFROM BorrowWHERE Borrow.Book_id in (SELECT Book_idFROM deleted)PRINT '该图书的借阅信息已删除! 'DELETEFROM HistoryWHERE History.Book_id in (SELECT Book_idFROM deleted)PRINT '该图书的被借阅历史已删除! ' DELETEFROM BookWHERE Book_id in(SELECT Book_idFROM deleted)PRINT '该图书已删除! '
END
3)存储过程
--存储过程查询某类图书的数量
CREATE PROCEDURE Book_Type_num@Book_type NVARCHAR(20)='自然科学'
ASSELECT Book_type, COUNT(Book.Book_id) '该类型的图书数量(一样的书只算一本)'FROM BookWHERE 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)
ASINSERT 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_passFROM AdminWHERE 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 FORSELECT Reader_id,Book_id,Borrow_timeFROM 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 FORSELECT Reader_id,Book_id,Borrow_time,Return_timeFROM 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_allnumFROM 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 DELETEFROM BookWHERE 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 FORSELECT Reader_id,Book_id,Borrow_timeFROM 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 FORSELECT Reader_id,Book_id,Borrow_time,Return_timeFROM 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 FORSELECT *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_allnumFROM 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_timeFROM BorrowWHERE 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_timeFROM BorrowWHERE 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 BorrowWHERE Reader_id=:LReader_num AND Book_id=:LBook_id;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1; }EXEC SQL UPDATE HistorySET Return_time=:LReturn_timeWHERE 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:LLNullFROM HistoryWHERE 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:LNullFROM 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 ReaderSET Reader_password=:LReader_password,Reader_name=:LReader_name,Reader_sex=:LReader_sex,Reader_age=:LReader_age,Reader_Company=:LReader_Company,Reader_work=:LReader_workWHERE 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:LNullFROM 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)读者管理界面
相关文章:

基于C语言+SQL Server2008实现(控制台)图书管理系统
第1章 概述 1.1项目背景 随着科技的发展,尤其是计算机技术的迅猛发展,图书馆管理的问题从以往的人工管理,到现在的电脑化,系统化,是对图书馆管理方法的质的飞跃,这些技术不仅让图书馆管理变得更加方便、快…...

Msf之Python分离免杀
Msf之Python分离免杀 ——XyLin. 成果展示: VT查杀率:8/73 (virustotal.com) 火绒和360可以过掉,但Windows Defender点开就寄掉了 提示:我用360测的时候,免杀过了,但360同时也申报了,估计要不了多久就寄…...

electron-updater实现electron全量版本更新
在 Electron 应用中使用 electron-updater 来实现自动更新功能时,通常你会在一个专门的模块或文件中管理更新逻辑。如果你想要使用 ES6 的 import 语法来引入 electron-updater,你需要确保你的项目已经配置好了支持 ES6 模块的构建工具(如 We…...

Mysql梳理6——order by排序
目录 6 order by排序 6.1 排序数据 6.2 单列排序 6.3 多行排列 6 order by排序 6.1 排序数据 使用ORDER BY字句排序 ASC(ascend):升序DESC(descend):降序 ORDER BY子句在SELECT语句的结尾 6.2 单列排序 如果没有使用排序操作,默认…...

Java设计模式—面向对象设计原则(三) -----> 依赖倒转原则DIP(完整详解,附有代码+案例)
文章目录 3.3 依赖倒转原则(DIP)3.3.1概述3.3.2 案例 3.3 依赖倒转原则(DIP) 依赖倒转原则:Dependency Inversion Principle,DIP 3.3.1概述 高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细…...

Linux操作系统 进程(3)
接上文 Linux进程优先级之后,我们了解到僵尸进程与孤儿进程的形成原因,既然是因为父进程没有接收子进程的退出状态导致的,那么我们该如何去获取子进程的退出状态呢?那本篇文章将围绕这个问题来解释进程。 环境 : vsco…...

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期]
QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期] 第五期介绍:频道模块之接口授权管理和发言管理 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期]第五期介绍:频道模块之接口授权管理和发言管理获取机器人在频道可用权限列表…...

代码签名证书快速申请指南
申请代码签名证书是确保软件或应用程序在分发和安装过程中不被篡改的重要步骤。以下是详细的快速申请指南: 一、选择证书品牌和服务商 选择知名证书品牌:首先,选择一个国际知名的代码签名证书品牌,如GlobalSign、Digicert、Comod…...

安卓 uniapp跨端开发
HBuilder X 4.24 本地插件方式使用原生插件 例如 MT-TTS 地址PS: 播放 speek({text: ‘test’}) 应为 播放 speak({text: ‘test’})MT-TTS下载下来之后,将 nativeplugins 文件夹拷贝到 uniapp 项目根目录中manifest.json ---- App原生插件配置 运行 语音引擎测试文字转语音播…...

【高阶用法】uniapp的i18n多语言模块修复与增强(Typescript)
痛点 在i18n多语言模块使用过程中,发现下面几个问题,需要解决 1)uni-best框架下,$t功能函数无法实时的切换语言,可能跟使用有关 2)uni-best建议的translate方式在vue块外使用太繁琐,希望不用…...

SQL Server Data Tools (SSDT)入门教程
SSDT (SQL Server Data Tools) 是微软提供的一款用于开发、设计和管理SQL Server数据库的工具。它集成在Visual Studio中,允许开发人员和数据库管理员在统一的环境中进行数据库开发与管理。以下是关于SSDT的详细介绍: 1. 什么是SSDT? SQL S…...

窗户检测系统源码分享
窗户检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …...

2.计算机网络基础
2. 计算机网络基础 (1) 计算机网络的定义 计算机网络是指将地理位置不同、具有独立功能的多个计算机系统通过通信线路和设备连接起来,以功能完善的网络软件实现网络中资源共享的系统。最简单的定义是:计算机网络是一些互相连接的、自治的计算机系统的集合。最庞大的计算机网…...

硬中断,软中断恢复位置
汇编初始化栈指针,interrupt,svc preserve8 ;preserve8 和 restore8 通常用于保护寄存器的状态;以确保在函数调用前后某些寄存器的值保持不变area reset,code,readonlycode32entryb startldr pc,do_undefined;这些地址不能随便写,0x0,0x4,0x8....这些…...

MySQL基础(13)- MySQL数据类型
目录 一、数据类型概述 1.MySQL中的数据类型 二、整型 1.数据类型可选属性 2.使用建议 三、浮点数、定点数、位类型 1.类型介绍 2.浮点类型 3.定点数类型 4.位类型 四、日期时间类型 1.YEAR 2.DATE 3.TIME 4.DATETIME 5.TIMESTAMP 6.TIMESTAMP和DATETIME的区别…...

数据结构------二叉树简单介绍及实现
如果不是满二叉树或者完全二叉树,就要用链式存储 //搜索二叉树:左子树的所有值比根小,右子树的所有值比根大 // 实现查找,最多找高度次(类似二分法) //二分查找存在的问题:…...

由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(六)
概述 在 WWDC 24 中,苹果推出了数据库框架 SwiftData 2.0 版本。听说里面新增了能让数据记录“借尸还魂”的绝妙法器,到底是真是假呢? 我们在上篇博文中介绍了 History Trace 是如何稳妥的处理数据删除操作的。而在这里,我们将继续介绍 SwiftData 2.0 中另一个新特性:“墓…...

尚品汇-秒杀下单实现-页面轮询查询订单状态(五十三)
目录: (1)整合秒杀业务 (2)秒杀下单 (3)秒杀下单监听 (4)页面轮询接口 (1)整合秒杀业务 秒杀的主要目的就是获取一个下单资格,拥…...

2024年微电子与纳米技术国际研讨会(ICMN 2024) Microelectronics and Nanotechnology
文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网:https://ais.cn/u/vEbMBz提交检索:EI Compendex、IEEE Xplore、Scopus大会时间:2024年9月20-22日地点:成都…...

2024最新版,人大赵鑫老师《大语言模型》新书pdf分享
本书主要面向希望系统学习大语言模型技术的读者,将重点突出核心概念与 算法,并且配以示例与代码(伪代码)帮助读者理解特定算法的实现逻辑。由于大语言模型技术的快速更迭,本书无法覆盖所有相关内容,旨在梳理…...

[Leetcode 543][Easy]-二叉树的直径-递归
目录 一、题目描述 二、整体思路 三、代码 一、题目描述 原题地址 二、整体思路 取一个结点的最大直径就是取一个结点的左子树最大深度右子树最大深度之和,因此可以定义一个递归函数,作用是取一个结点的最大直径。这个函数中还实现了求左子树最大深度…...

高级大数据开发学习路线指南
掌握大数据技术是一项系统性工程,涉及到广泛的技能和专业知识。为了帮助初学者构建坚实的基础,并逐步成长为大数据领域的专家,下面详细阐述了一条全面而深入的学习路线: 1. Java 编程基础 - 打造坚实的底层技能 关键知识点&…...

SpringBoot设置mysql的ssl连接
因工作需要,mysql连接需要开启ssl认证,本文主要讲述客户端如何配置ssl连接。 开发环境信息: SpringBoot: 2.0.5.RELEASE mysql-connector-java: 8.0.18 mysql version:8.0.18 一、检查服务端是否开启ssl认…...

2024-1.2.12-Android-Studio配置
本地博客: https://k1t0111.github.io/ K1T0 最近在做一些app方向的移动技术开发学习,但是由于AS的配置问题,市面上找不到最新的2024版本的AS的相关配置。笔者也是踩了很多坑,因此想写一篇文章记录一下最新的AS 2024 1.2.12的对应java环境的一…...

前端vue左侧树的一整套功能实现(一):vue2+vite封装v-resize指令,实现左侧树拖拽宽度和折叠展开
实现v-resize指令,具体以下功能: 指令接收宽度最大最小值,接收一个id用于localStorage存储拖拽宽度,接收padding拖拽时产生虚线拖拽,松开鼠标再进行元素宽度调整折叠展开图标使用本地图片 封装一个vite下使用本地图片…...

本地部署huggingface模型,建立自己的翻译应用
过去,我们使用翻译接口时,往往都是使用百度等的接口,每天有一定量的免费额度。今天为大家介绍一个可以进行翻译的模型,具备英译中、中译英的能力。并且在这个过程中,向大家介绍一个如何在本地部署模型。在之前的”五天…...

基于python+django+vue的在线学习资源推送系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…...

.Net Gacutil工具(全局程序集缓存工具)使用教程
GAC介绍: GAC(Global Assembly Cache)全局程序集缓存,是用于存放.Net应用程序共享的程序集。 像平常我们在Visual Studio中引用系统程序集时,这些程序集便来自于GAC。 GAC默认位置为:%windir%\Microsoft…...

安卓13修改设置设备型号和设备名称分析与更改-android13设置设备型号和设备名称更改
总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 用户要定制一些系统显示的设备型号和设备名称,这就需要我们分析设置里面的相关信息来找到对应的位置进行修改了。 2.问题分析 像这种信息要么是config.xml里面写死了,要…...

AI健身体能测试之基于paddlehub实现引体向上计数个数统计
【引体向上计数】 本项目使用PaddleHub中的骨骼检测模型human_pose_estimation_resnet50_mpii,进行人体运动分析,实现对引体向上的自动计数。 1. 项目介绍 人体运动分析是近几年许多领域研究的热点问题。在学科的交叉研究上,人体运动分析涉…...