书店管理系统课程设计( sql server+python)
作者:mmseoamin日期:2023-12-25

文章目录

  • 一. 概述
  • 二. 需求分析
  • 三. 概念设计
    • 1. 抽象出实体
    • 2. 实体属性图和分E-R图
    • 四. 逻辑结构设计
    • 五. 数据库物理设计与实施
      • 1. 物理结构设计
      • 2. 表的创建
      • 3. 完整性约束
      • 六. 数据库操作要求及实现
      • 七. python对sql server操作(嵌入式sql语言的实现)
        • 1. 连接sql server数据库
        • 2. 增删查改功能
        • 3. 其他功能
        • 八. 总结
        • 九. 源码
          • 1. 完整sql语句
          • 2. python源码

            一. 概述

            根据课程要求,我需要完成一个数据库课程设计。结合实际,我选择了相对比较熟悉的书店作为我的设计对象,根据网上查阅和询问,我得知了书店的一些日常的工作和数据的内容和类型,于是我进行了需求分析,并制定了E-R模型,来分析了数据库的设计样式和需求。

            二. 需求分析

            根据书店的需求,书店的日常,主要分为四种情况:

            1. 进货:每一本图书,都有着图书类型,图书价格,图书出版商,图书的版本等图书的信息,筛选好图书然后整理好图书信息,才能进货。
            2. 入库:将图书进货后,需要确定图书是否在库中已有,如果没有此类的图书信息,需要将图书的基本信息存入库中,并且添加入库的图书的数量;如果有相同的图书信息,则不需要录入图书信息,而直接更新图书的现有数量。
            3. 销售:销售出去的书也要记录书的信息,确定好书籍的信息才能记录并售出。
            4. 出库:对于销售出去的书籍要及时更新数据,对现有的书籍数量进行更新检查,并且记录销售记录,以便为以后的进货作参考,如果书籍售空,这可以提醒操作员进货。

            三. 概念设计

            1. 抽象出实体

            根据数据库的需要,可以抽象出下面实体:

            1. 图书信息
            2. 顾客信息
            3. 供应商信息
            4. 库存信息
            5. 进货信息
            6. 销售信息

            2. 实体属性图和分E-R图

            下面是各个实体的属性图,以及分E-R图:

            图1 图书信息实体属性图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第1张

            图2 顾客信息实体属性图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第2张

            图3 供应商信息实体属性图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第3张

            图4 库存信息实体属性图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第4张

            图5 进货分E-R图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第5张

            图6 销售分E-R图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第6张

            图7 全局总E-R图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第7张

            四. 逻辑结构设计

            关系数据模式如下:

            1. 图书信息: 书号, 图书名称, 图书分类, 图书出版社, 价格, 图书页数
            2. 顾客信息:  顾客号,顾客姓名,顾客性别,顾客年龄,顾客电话号码
            3. 供应商信息:供应商号, 供应书号,供应商名称, 供应商电话号码,供应数量
            4. 进货信息:书号,进货商号,供应商号,图书进货数量,进货日期
            5. 销售信息 : 销售单号,销售日期, 图书名称, 顾客信息,数量,总价
            6. 库存信息: 图书名称, 图书的种类,库存图书数量

            五. 数据库物理设计与实施

            1. 物理结构设计

            根据逻辑结构设计得到逻辑数据模型,制定的数据库物理模型如下,其中引入了6张表,分别是“进货信息”,“供应商信息”,“库存信息”,“顾客信息”,“销售信息”,“图书信息”

            图8 数据库物理模型图

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第8张

            2. 表的创建

            表1 图书信息表

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第9张

            create table 图书信息(
            	书号 nchar(10) foreign key references 库存信息(书号),
            	图书名称 nchar(20) NOT NULL ,
            	图书类别 nchar(20) NOT NULL ,
            	图书出版社 nchar(20) NOT NULL,
            	图书价格 float not null,
            	图书页数 int not null
            )
            

            表2 顾客信息表

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第10张

            create table 顾客信息(
            	顾客号 nchar(10) NOT NULL PRIMARY KEY,
            	姓名 nchar(20) NOT NULL,
            	性别 nchar(20) NOT NULL,
            	年龄 int NOT NULL,
            	电话号码 nchar(20) not null,
            	)
            

            表3 供应商信息表

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第11张

            create table 供应商信息(
            	供应商号 nchar(10) NOT NULL PRIMARY KEY,
            	供应商名称 nchar(20) NOT NULL,
            	电话号码 nchar(20) NOT NULL,
            	供应商地址 nchar(40) not null 
            )
            

            表4 进货信息表

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第12张

            create table 进货信息(
            	进货单号 nchar(10) NOT NULL PRIMARY KEY,
            	书号 nchar(10) not NULL,
            	图书类别 nchar(20) not NULL,
            	供应商号 nchar(10) foreign key references 供应商信息(供应商号),
            	图书进货数量 int NOT NULL,
            	进货日期 date default (getdate())
            )
            

            表5 销售信息表

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第13张

            create table 销售信息(
            	销售单号 nchar(10) NOT NULL PRIMARY KEY,
            	书号 nchar(10) foreign key references 库存信息(书号),
            	顾客号 nchar(10) foreign key references 顾客信息(顾客号),
            	图书销售数量 int NOT NULL,
            	销售日期 date default (getdate()),
            	销售金额 float null default (0)
            )
            

            表6 库存信息表

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第14张

            create table 库存信息(
            	书号 nchar(10) PRIMARY KEY, 
            	图书类别 nchar(20) not null,
            	图书数量 int not null
            )
            

            3. 完整性约束

            --设置完整性约束
            --设置销售金额默认值是
            alter table 销售信息 add default(0) for 销售金额
            --设置级联删除更新,当库存信息中书号改变,图书信息中的学号也改变,当库存信息中数据删除时,图书中的数据也级联删除
            alter table 图书信息 add constraint 库存删除 foreign key(书号) references 库存信息(书号) on delete CASCADE on update cascade
            --设置库存信息和销售信息级联更新
            alter table 销售信息 add constraint 销售更新 foreign key(书号) references 库存信息(书号) on update cascade 
            --进货信息与库存信息之间级联删除更新
            alter table 进货信息 add constraint 进货删除 foreign key(书号) references 库存信息(书号) on delete CASCADE on update cascade
            --进货信息和供应商信息设置级联删除更新,使数据保持一致
            alter table 进货信息 add constraint 供应商删除 foreign key(供应商号) references 供应商信息(供应商号) on delete CASCADE on update cascade
            --销售信息与顾客信息建立级联删除,并在顾客号上,建立级联更新,以便数据更改。
            alter table 销售信息 add constraint 顾客删除 foreign key(顾客号) references 顾客信息(顾客号) on delete CASCADE on update cascade
            

            六. 数据库操作要求及实现

            根据课程设计需求并且结合数据库的设计,对一些功能的实现,我做了详细的分析,下面涉及了存储过程和触发器,运用了相关的技术,需求sql语句如下:

            1. 创建存储过程查询某段时间内各种图书的进货和销售情况;

            create procedure 进售信息
            	@date1 date,
            	@date2 date	
            	AS
            	select * from 进货信息 where 进货信息.进货日期>=@date1 and 进货信息.进货日期<=@date2
            	select * from 销售信息 where 销售日期>=@date1 and 销售日期<=@date2
            	go
            --用于exec语句传参并使用存储结构
            	exec 进售信息 '2020-1-20','2020-1-23'
            

            执行结果:

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第15张

            2. 创建视图查询各类图书的库存总数;

            create view zl_numb 
            as 
             select 图书类别,sum(图书数量) as 种类数量 from 库存信息 group by 图书类别
             go
            

            执行结果:

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第16张

            3. 创建触发器当图书入库时自动修改相应图书的总量和存放仓库中该图书的数量,当图书库存数量为0时,删除该书库存信息和图书信息,当进货新书时自动添加到库存信息中;

            -- 进货入库
            	CREATE TRIGGER 库存增加 on 进货信息 for insert AS
            	declare @num int
            	declare @bnum nchar(10)
            	declare @f  int
            	declare @kinds nchar(20)
            	select @num=图书进货数量,@bnum=书号,@kinds=图书类别 from inserted
            	select @f=COUNT(@bnum)from 库存信息 where 书号=@bnum
            	if @f>0
            	begin
            	update 库存信息 set 图书数量=图书数量+@num where 书号=@bnum
            	end
            	if @f<=0
            	begin
            		insert into 库存信息 values (@bnum,@kinds,@num)
            	end
            	go
            --销售出库
            	CREATE TRIGGER 库存减少 on 销售信息 for insert AS
            		declare @num int
            		declare @bnum nchar(10)
            		declare @num1 int
            		select @num=图书销售数量,@bnum=书号 from inserted
            		select @num1=图书数量 from 库存信息 where @bnum=书号
            		if @num1 <= @num
            			begin
            			if @num1=@num
            			begin
            			delete 库存信息 where 书号=@bnum
            			end
            			else
            			begin
            			print '销售失败,图书数量不够!'
            			Rollback TRANSACTION
            			end
            			end
            		else
            			begin
            			update 库存信息 set 图书数量=图书数量-@num where 书号=@bnum
            			end
            		go
            

            修改前库存信息和进货信息:

            下图为库存信息

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第17张

            下图为进货信息

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第18张

            下面进货2本书号为001的书:

            insert into 进货信息 (进货单号,书号,图书类别,供应商号,图书进货数量)values('a4','001','中国古代小说','01',2)
            

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第19张

            执行后库存信息如下,成功实现了功能

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第20张

            下面测试销售出库功能

            销售前销售的信息如下 :

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第21张

            下面插入一条销售数据,售出001号书2本,但在销售之前需要将书上架,也就是把进货的书的信息完善一下,定一下售价。

            Sql语句如下:

            insert into 图书信息 values ('001','水浒传','中国古代小说','新华出版社',45.2,540)
            

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第22张

            insert into 销售信息 (销售单号,书号,顾客号,图书销售数量) 
            values ('b1','001','1',2)
            

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第23张

            执行后库存结果:

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第24张

            结合实际情况我设计了进货新书直接加入库存

            Sql语句:

            insert into 进货信息 (进货单号,书号,图书类别,供应商号,图书进货数量)values('a5','005','中国散文','01',20)
            

            进货信息

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第25张

            进货后的库存信息

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第26张

            当库存图书的数量为0时,会自动删除该库存信息图书信息。

            4. 创建触发器销售信息金额自动结算

            Sql 语句:
            create trigger 结账金额 on 销售信息 for insert as 
                declare @图书价格 float
                declare @销售数量 int 
                declare @销售单号 nchar(10)
                declare @书号 nchar(10)
                select @销售数量=图书销售数量,@销售单号=销售单号,@书号=书号 from inserted
                select @图书价格=图书价格 from 图书信息 where @书号=书号
                update 销售信息 set 销售金额=@图书价格*@销售数量 where @销售单号=销售单号
            go
            

            测试sql语句:

            insert into 销售信息 (销售单号,书号,顾客号,图书销售数量) values ('b2','001','1',2)
            

            测试前销售信息

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第27张

            执行结果

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第28张

            5. 创建触发器对顾客的性别(只能是男或女)和年龄(10-150岁)进行约束

            --对顾客性别进行约束
            	create trigger 性别约束 on 顾客信息 for insert 
            	as 
            	declare @性别 nchar(20)
            	declare @年龄 int
            	select @性别=性别,@年龄= 年龄 from inserted
            	if @性别!='男' and @性别!='女'
            	begin
            	print '性别格式错误!'
                Rollback TRANSACTION
            	end
            	if @年龄 not between 10 and 150
            	begin
            	print '年龄超出范围,必须在-150岁之间!'
                Rollback TRANSACTION
                end
            	go
            

            测试语句:

            insert into 顾客信息 values ('5','王小壮','男',30,'1258468720')
            insert into 顾客信息 values ('6','王大壮','男',9,'1258468720')
            

            测试前顾客信息

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第29张

            测试结果

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第30张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第31张

            七. python对sql server操作(嵌入式sql语言的实现)

            为了使数据库能够得到更加合理的运用,将其功能同实际联系起来,我用python高级程序语言写了一个书店小项目,其中运用了嵌入式sql语言,有基本的增删查改功能,我使用的编程工具是pycharm 。主要功能如下 :

            1. 进货
            2. 查看/上架图书
            3. 查看/新增供应商
            4. 查看/新增会员
            5. 结账
            6. 查看进货和销售记录
            7. 查看库存容量
            8. 离开

            下面就来讲述一下各个功能的主要设计原理和实现功能的方法。

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第32张

            1. 连接sql server数据库

            首先需要导入pymssql库,然后才能使用数据库操作的一些方法,同时也要在sql server中要建立一个可登录的用户,其中需要用到 pymssql.connect()方法,进行连接数据库,填入数据库访问地址(url),数据库的用户名和密码,还有数据库的名称,数据库的端口,这个默认是1433,但也有活动端口,最后还要写入读取的编码格式,防止乱码。

            代码如下:

            # 数据库连接
            import pymssql
                def sql_server_conn(self):
                   connect = pymssql.connect(self.url, self.username, self.password, self.databaseName, port=self.port,charset=self.charset)  
            # 服务器名,账户,密码,数据库名
                    if connect:
                        print(u"Success!!")
                    return connect
            

            2. 增删查改功能

            增删改功能是运用了pymssql .execute()和pymssql .commit() 方法,而查找则用pymssql .execute()和pymssql.fetchall()方法。都需要结合相关的内嵌式sql语句才能操作数据库中的数据信息,为了保障程序的合理性,也要设置一些异常捕捉,在sql语句出错时能够正常结束进程。

            代码如下:

             # 执行sql语句,增删改查
                def execute_sql(self, sql):
                    try:
                        s1 = ''
                        sql = sql.lower()
                        if 'insert' in sql or 'delete' in sql or 'update' in sql:
                            self.cursor.execute(sql)
                            self.connect.commit()
                            return
                        elif 'select' in sql:
                            self.cursor.execute(sql)
                            rows = self.cursor.fetchall()
                            for k in rows:
                                for k1 in k:
                                    s1 += (str(k1).strip(' ')) + "\t\t"
                                s1 += '\n'
                            if s1 == '':
                                print("无")
                            print(s1)
                    except :
                        print("3[1;31m 输入sql语句错误!自动返回菜单!3[0m")
            

            3. 其他功能

            其他的功能都大同小异,除了顺序流程上的基本设计,其他对数据库的操作也都用到了上面增删查改用到的方法。在此不再一一讲述,下面给出功能运行截图。

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第33张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第34张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第35张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第36张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第37张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第38张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第39张

            书店管理系统课程设计( sql server+python),在这里插入图片描述,第40张

            八. 总结

            这个课程设计花费了我不少的时间,但我在其中也得到了很多东西,sql server学了半学期,重来没有这么透彻过,首先我对sql语言的各个部分都系统的串联了一遍,更加熟悉了触发器,级联操作,存储过程,约束条件,这些使得一些杂乱的数据变得井然有序。当然在表的设计也是有很多讲究,表的结构往往决定了后面设计的难度,这点我深刻的体会到了,在设计书店管理系统的时候我就发现自己的构造有些问题,不能很直接的插入想要的数据,于是在后来我改了将近6遍,才觉得表结构合理,这也给了我一个教训,在开始导入数据的时候一定要构思好表的结构。

            其次在实现内嵌式sql语言的时候,需要连接sql server ,这就需要自己动手去查找一些网上的资料,刚开始怎么也连不上,最后发现是端口的问题,连接上以后,又由于中文问题导致部分乱码,我整了一晚上才解决,是属性数据类型的问题,于是我改成了nchar类型的,它使用的是unicode编码,不会出现乱码的情况,于是我又学到了解决乱码的方法。

            九. 源码

            1. 完整sql语句

            --创建数据库
            create database bookshop
            --建立基本表
            	use bookshop
            	create table 图书信息(
            	书号 nchar(10) foreign key references 库存信息(书号),
            	图书名称 nchar(20) NOT NULL ,
            	图书类别 nchar(20) NOT NULL ,
            	图书出版社 nchar(20) NOT NULL,
            	图书价格 float not null,
            	图书页数 int not null
            )
            create table 顾客信息(
            	顾客号 nchar(10) NOT NULL PRIMARY KEY,
            	姓名 nchar(20) NOT NULL,
            	性别 nchar(20) NOT NULL,
            	年龄 int NOT NULL,
            	电话号码 nchar(20) not null,
            	)
            	create table 供应商信息(
            	供应商号 nchar(10) NOT NULL PRIMARY KEY,
            	供应商名称 nchar(20) NOT NULL,
            	电话号码 nchar(20) NOT NULL,
            	供应商地址 nchar(40) not null 
            )
            create table 进货信息(
            	进货单号 nchar(10) NOT NULL PRIMARY KEY,
            	书号 nchar(10) not NULL,
            	图书类别 nchar(20) not NULL,
            	供应商号 nchar(10) foreign key references 供应商信息(供应商号),
            	图书进货数量 int NOT NULL,
            	进货日期 date default (getdate())
            )
            create table 销售信息(
            	销售单号 nchar(10) NOT NULL PRIMARY KEY,
            	书号 nchar(10) foreign key references 库存信息(书号),
            	顾客号 nchar(10) foreign key references 顾客信息(顾客号),
            	图书销售数量 int NOT NULL,
            	销售日期 date default (getdate()),
            	销售金额 float null default (0)
            )
            create table 库存信息(
            	书号 nchar(10) PRIMARY KEY, 
            	图书类别 nchar(20) not null,
            	图书数量 int not null
            )
            --添加数据
            insert into 图书信息 values ('001','水浒传','中国古代小说','新华出版社',45.2,540)
            insert into 图书信息 values ('002','战争与和平','外国小说','外国出版社',30.0,440)
            insert into 图书信息 values ('003','三国演义','中国古代小说','新华出版社',45.5,540)
            insert into 图书信息 values ('004','朝花夕拾','中国近代散文','新华出版社',30.1,540)
            select * from 图书信息
            insert into 顾客信息 values 
            ('1','王壮','男',30,'1258468720'),
            ('2','张力','男',35,'1845846872'),
            ('3','马超','男',20,'5896668720'),
            ('4','小红','女',18,'1598468720')
            select * from 顾客信息
            insert into 顾客信息 values 
            ('6','王小壮','男',30,'1258468720')
            insert into 供应商信息 values 
            ('01','好再来','5265655','平顶山学院'),
            ('02','德利','5265655','平顶山学院'),
            ('03','华夏好书','5265655','平顶山学院'),
            ('04','武功秘籍','5265655','平顶山学院')
            select * from 供应商信息
            delete 供应商信息 where 供应商号='hjgh'
            insert into 进货信息 (进货单号,书号,图书类别,供应商号,图书进货数量)values('a1','005','中国散文','01',20)
            insert into 进货信息 (进货单号,书号,供应商号,图书进货数量)values('a2','002','外国小说','01',20)
            insert into 进货信息 (进货单号,书号,供应商号,图书进货数量)values('a3','005','中国散文','01',20)
            insert into 进货信息 (进货单号,书号,供应商号,图书进货数量)values('a4','001','中国古代小说','01',2) 
            insert into 进货信息 (进货单号,书号,供应商号,图书进货数量)values('a5','005','中国散文','02',20) 
            select * from 进货信息
            insert into 销售信息 (销售单号,书号,顾客号,图书销售数量) values ('b2','001','1',2)
            select * from 销售信息
            delete from 销售信息
            insert into 库存信息 values ('001','中国古代小说',10)
            insert into 库存信息 values ('002','外国小说',20)
            insert into 库存信息 values ('003','中国古代小说',20)
            insert into 库存信息 values ('004','中国近代散文',20)
            select * from 库存信息
            delete 库存信息 where 书号='003'
            -- 存储过程设置
            --1. 创建存储过程查询某段时间内各种图书的进货和销售情况;
            create procedure 进售信息
            	@date1 date,
            	@date2 date	
            	AS
            	select * from 进货信息 where 进货信息.进货日期>=@date1 and 进货信息.进货日期<=@date2
            	select * from 销售信息 where 销售日期>=@date1 and 销售日期<=@date2
            	go
            	
            	exec 进售信息 '2021-12-22','2021-12-23'
            	drop procedure jx_list
            	
            -- 创建视图
            --1. 创建视图查询各类图书的库存总数;
            create view zl_numb 
            as 
             select 图书类别,sum(图书数量) as 种类数量 from 库存信息 group by 图书类别
             go 
             select * from zl_numb
             
             
             --触发器
             
            --1. 创建触发器当图书入库时自动修改相应图书的总量和存放仓库中该图书的数量;  
              -- 进货入库
            	CREATE TRIGGER 库存增加 on 进货信息 for insert AS
            	declare @num int
            	declare @bnum nchar(10)
            	declare @f  int
            	declare @kinds nchar(20)
            	select @num=图书进货数量,@bnum=书号,@kinds=图书类别 from inserted
            	select @f=COUNT(@bnum)from 库存信息 where 书号=@bnum
            	if @f>0
            	begin
            	update 库存信息 set 图书数量=图书数量+@num where 书号=@bnum
            	end
            	if @f<=0
            	begin
            		insert into 库存信息 values (@bnum,@kinds,@num)
            	end
            	go
            	
            	drop trigger 库存增加
            --销售出库
            	CREATE TRIGGER 库存减少 on 销售信息 for insert AS
            		declare @num int
            		declare @bnum nchar(10)
            		declare @num1 int
            		select @num=图书销售数量,@bnum=书号 from inserted
            		select @num1=图书数量 from 库存信息 where @bnum=书号
            		if @num1 <= @num
            			begin
            			if @num1=@num
            			begin
            			delete 库存信息 where 书号=@bnum
            			end
            			else
            			begin
            			print '销售失败,图书数量不够!'
            			Rollback TRANSACTION
            			end
            			end
            		else
            			begin
            			update 库存信息 set 图书数量=图书数量-@num where 书号=@bnum
            			end
            		go
            -- 自动填入金钱数量
                create trigger 结账金额 on 销售信息 for insert as 
                declare @图书价格 float
                declare @销售数量 int 
                declare @销售单号 nchar(10)
                declare @书号 nchar(10)
                select @销售数量=图书销售数量,@销售单号=销售单号,@书号=书号 from inserted
                select @图书价格=图书价格 from 图书信息 where @书号=书号
                update 销售信息 set 销售金额=@图书价格*@销售数量 where @销售单号=销售单号
                go
                
            	
            	--对顾客性别进行约束
            	create trigger 性别约束 on 顾客信息 for insert 
            	as 
            	declare @性别 nchar(20)
            	declare @年龄 int
            	select @性别=性别,@年龄= 年龄 from inserted
            	if @性别!='男' and @性别!='女'
            	begin
            	print '性别格式错误!'
                Rollback TRANSACTION
            	end
            	if @年龄 not between 10 and 150
            	begin
            	print '年龄超出范围,必须在-150岁之间!'
                Rollback TRANSACTION
                end
            	go
            	
            --设置完整性约束
            --设置销售金额默认值是
            alter table 销售信息 add default(0) for 销售金额
            --设置级联删除更新,当库存信息中书号改变,图书信息中的学号也改变,当库存信息中数据删除时,图书中的数据也级联删除
            alter table 图书信息 add constraint 库存删除 foreign key(书号) references 库存信息(书号) on delete CASCADE on update cascade
            --设置库存信息和销售信息级联更新
            alter table 销售信息 add constraint 销售更新 foreign key(书号) references 库存信息(书号) on update cascade 
            --进货信息与库存信息之间级联删除更新
            alter table 进货信息 add constraint 进货删除 foreign key(书号) references 库存信息(书号) on delete CASCADE on update cascade
            --进货信息和供应商信息设置级联删除更新,使数据保持一致
            alter table 进货信息 add constraint 供应商删除 foreign key(供应商号) references 供应商信息(供应商号) on delete CASCADE on update cascade
            --销售信息与顾客信息建立级联删除,并在顾客号上,建立级联更新,以便数据更改。
            alter table 销售信息 add constraint 顾客删除 foreign key(顾客号) references 顾客信息(顾客号) on delete CASCADE on update cascade
            

            2. python源码

            # import pymssql
            # serverName = '127.0.0.1'    #目的主机ip地址
            # userName = 'zpx'        #SQL Server身份账号
            # passWord = '123'        #SQL Server身份密码
            # dbName = 'bookshop'        #对应数据库名称
            # connect = pymssql.connect(serverName,userName, passWord,dbName,port='49680') #SQL Server身份验证建立连接
            # # connect = pymssql.connect(server = serverName , database = dbName) #Window默认身份验证建立连接
            #
            # if connect:
            #     print("连接成功!")
            import pymssql
            import msvcrt
            from pykeyboard import *
            import time
            import traceback, sys
            import switch as switch
            class database(object):
                """数据库操作对象"""
                def __init__(self, url, username, password, databaseName, port, charset):
                    self.url = url
                    self.username = username
                    self.password = password
                    self.databaseName = databaseName
                    self.port = port
                    self.charset = charset
                    self.connect = self.sql_server_conn()
                    self.cursor = self.connect.cursor()
                def sql_server_conn(self):
                    connect = pymssql.connect(self.url, self.username, self.password, self.databaseName, port=self.port,
                                              charset=self.charset)  # 服务器名,账户,密码,数据库名
                    if connect:
                        print(u"Success!!")
                    return connect
                # 查看表的所有字段,
                # @table_name :表名
                def get_column_name(self, table_name):
                    self.cursor.execute("select top 1 * from " + table_name)  # 执行sql语句
                    data_dict = []
                    for field in self.cursor.description:
                        data_dict.append(field[0])
                    print(data_dict)
                    return data_dict
                # 得到数据库所有的表名
                def get_table_name(self):
                    sql = "SELECT NAME FROM SYSOBJECTS WHERE XTYPE='U' ORDER BY NAME"
                    self.cursor.execute(sql)  # 返回执行成功的结果条数
                    rows = self.cursor.fetchall()
                    for d in rows:
                        for k in d:
                            print(k)
                # 执行sql语句,增删改查
                # @sql:sql语句
                def execute_sql(self, sql):
                    try:
                        s1 = ''
                        sql = sql.lower()
                        if 'insert' in sql or 'delete' in sql or 'update' in sql:
                            self.cursor.execute(sql)
                            self.connect.commit()
                            return
                        elif 'select' in sql:
                            self.cursor.execute(sql)
                            rows = self.cursor.fetchall()
                            print("进货单号\t书号\t\t图书类型\t\t供应商号\t图书进货数量\t进货日期")
                            for k in rows:
                                for k1 in k:
                                    s1 += (str(k1).strip(' ')) + "\t\t"
                                s1 += '\n'
                            if s1 == '':
                                print("无")
                            print(s1)
                    except :
                        print("3[1;31m 输入sql语句错误!自动返回菜单!3[0m")
                def InGoods(self):
                    # 先确定进货单号,再进货
                    sql = 'select 进货单号 from 进货信息'
                    s=''
                    self.cursor.execute(sql)
                    rows = self.cursor.fetchall()
                    for k in rows:
                        for k1 in k:
                            s += (str(k1).strip(' ')) + " "
                    print("已有进货单号:")
                    if s == '':
                        print("无")
                    print(s)
                    num = input("请输入进货单号:")
                    bnum=input("请输入书号:")
                    kinds = input("请输入图书类型:")
                    inshopnum=input("请输入供应商号:")
                    snum=input("请输入图书进货数量:")
                    sql = "insert into 进货信息(进货单号,书号,图书类别,供应商号,图书进货数量) values ('" + num + "','" + bnum+ "','" + kinds+"','" + inshopnum + "',"+ snum+" )"
                    self.execute_sql(sql)
                def sale(self):
                    chose=input("你是要查看,还是添加? C/A")
                    s = ''
                    if chose == 'A' or chose == 'a':
                        sql = 'select 书号 from 图书信息'
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        for k in rows:
                            for k1 in k:
                                s += (str(k1).strip(' ')) + " "
                        print("已上架书号:")
                        if s=='':
                            print("无")
                        print(s)
                        sql = 'select 书号 from 库存信息'
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        for k in rows:
                            for k1 in k:
                                s += (str(k1).strip(' ')) + " "
                        print("库存内书号:")
                        if s == '':
                            print("无")
                        print(s)
                        num = input("请输入要上架书号:")
                        bname = input("请输入图书名:")
                        kinds = input("请输入图书类别:")
                        cbs = input("请输入图书出版社:")
                        price = input("请输入图书价格:")
                        ynum = input("请输入图书页数:")
                        sql = "insert into 图书信息 values ('" + num + "','" + bname + "','" + kinds + "','" + cbs + "'," + price + "," + ynum + ")"
                        print("正在上架...")
                        if self.execute_sql(sql):
                            print("上架成功")
                    if chose == 'c' or chose == 'C':
                        s1 = ''
                        bnum = input("请输入书号:")
                        sql = "select * from 图书信息 where 书号= '" + bnum + "'"
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        print("书号\t图书名称\t 图书类别\t图书出版社\t图书价格\t图书页数")
                        for k in rows:
                            for k1 in k:
                                s1 += (str(k1).strip(' ')) + "\t"
                            s1 += '\n'
                        if s1 == '':
                            print("无此图书")
                        print(s1)
                def InShoper(self):
                    chose=input("你是要查看,还是添加? C/A:")
                    sql = 'select 供应商号 from 供应商信息'
                    s = ''
                    if chose=='A' or chose=='a':
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        for k in rows:
                            for k1 in k:
                                s += (str(k1).strip(' ')) + " "
                        print("已有供应商号:")
                        if s == '':
                            print("无")
                        print(s)
                        num = input("请输入供应商号:")
                        name = input("请输入供应商名称:")
                        tel = input("请输入供应商电话:")
                        add = input("请输入供应商地址:")
                        # sql=('insert into 供应商信息 values (%s,%s,%s,%s)'%(num,name,tel,add))
                        sql = "insert into 供应商信息 values ('" + num + "','" + name + "','" + tel + "','" + add + "')"
                        con.execute_sql(sql)
                        chose='C'
                    elif chose=='c' or chose=='C':
                        s1 = ''
                        self.cursor.execute('select * from 供应商信息')
                        rows = self.cursor.fetchall()
                        print('现有供应商如下:')
                        print("供应商号\t供应商名称\t供应商电话\t供应商地址")
                        for k in rows:
                            for k1 in k:
                                s1 += (str(k1).strip(' ')) + "\t\t"
                            s1 += '\n'
                        if s1 == '':
                            print("无")
                        print(s1)
                    else:
                        print("输入错误!")
                def Customer(self):
                    chose = input("你是要查看,还是添加? C/A:")
                    sql = 'select 顾客号 from 顾客信息'
                    s = ''
                    if chose == 'A' or chose == 'a':
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        for k in rows:
                            for k1 in k:
                                s += (str(k1).strip(' ')) + " "
                        print("已有顾客号:")
                        if s == '':
                            print("无")
                        print(s)
                        num = input("请输入顾客号:")
                        name = input("请输入顾客姓名:")
                        tel = input("请输入顾客电话:")
                        age = input("请输入顾客年龄: ")
                        sex = input("请输入顾客性别:")
                        # sql=('insert into 供应商信息 values (%s,%s,%s,%s)'%(num,name,tel,add))
                        sql = "insert into 顾客信息 values ('" + num + "','" + name + "','" + sex + "'," + age + ",'" + tel + "')"
                        # print(sql)
                        con.execute_sql(sql)
                    if chose == 'c' or chose == 'C':
                        s1 = ''
                        gknum=input("请输入顾客号:")
                        sql="select * from 顾客信息 where 顾客号= '"+gknum+"'"
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        print("顾客号\t顾客姓名\t顾客性别\t顾客年龄\t\t顾客电话")
                        for k in rows:
                            for k1 in k:
                                s1 += (str(k1).strip(' ')) + "\t\t"
                            s1 += '\n'
                        if s1 == '':
                            print("无")
                        print(s1)
                def CheckOut(self):
                    sql = 'select 销售单号 from 销售信息'
                    s = ''
                    self.cursor.execute(sql)
                    rows = self.cursor.fetchall()
                    for k in rows:
                        for k1 in k:
                            s += (str(k1).strip(' ')) + " "
                    print("已用销售单号:")
                    if s == '':
                        print("无")
                    print(s)
                    num = input("请输入销售单号:")
                    name = input("请输入书号:")
                    uname = input("请输入顾客号:")
                    add = input("请输入销售图书数量:")
                    # sql=('insert into 供应商信息 values (%s,%s,%s,%s)'%(num,name,tel,add))
                    sql = "insert into 销售信息(销售单号,书号,顾客号,图书销售数量) values ('" + num + "','" + name + "','" + uname + "'," + add + ")"
                    # print(sql)
                    con.execute_sql(sql)
                    s1 = ''
                    try:
                        sql="select 销售金额 from 销售信息 where 销售单号= '"+num+"'"
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                    except:
                        print("sql语句错误!")
                    for k in rows:
                        for k1 in k:
                            s1=(str(k1).strip(' '))
                    print("应付金额 :"+s1)
                def record(self):
                    chose= input("查看哪个记录?1.进货记录 2.销售记录:")
                    if chose=='1':
                        s1=''
                        sql = 'select * from 进货信息'
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        print("进货单号\t书号\t\t图书类别\t\t供应商号\t图书进货数量\t进货日期")
                        for k in rows:
                            for k1 in k:
                                s1 += (str(k1).strip(' ')) + "\t\t"
                            s1 += '\n'
                        if s1 == '':
                            print("无")
                        print(s1)
                    if chose=='2':
                        s1 = ''
                        sql = 'select * from 销售信息'
                        self.cursor.execute(sql)
                        rows = self.cursor.fetchall()
                        print("销售单号\t书号\t 顾客号\t图书销售数\t销售日期\t\t  销售金额")
                        for k in rows:
                            for k1 in k:
                                s1 += (str(k1).strip(' ')) + "\t\t"
                            s1 += '\n'
                        if s1 == '':
                            print("无")
                        print(s1)
                    else:
                        print("输入错误!")
                def Stock(self):
                    s1 = ''
                    sql = 'select * from 库存信息'
                    self.cursor.execute(sql)
                    rows = self.cursor.fetchall()
                    print("书号\t\t图书类别 \t库存量")
                    for k in rows:
                        for k1 in k:
                            s1 += (str(k1).strip(' ')) + "\t\t"
                        s1 += '\n'
                    if s1 == '':
                        print("无")
                    print(s1)
                def menu(self):
                    print("欢迎来到书店!")
                    while True:
                        print("服务菜单如下:")
                        print('1.进货')
                        print('2.查看/上架图书')
                        print('3.查看/新增供应商')
                        print('4.查看/新增会员')
                        print('5.结账')
                        print('6.查看进货和销售记录')
                        print('7.查看库存容量')
                        print('0.离开')
                        key = input("请选择需要的服务:")
                        if key == '1':
                            con.InGoods()
                            input("按回车继续")
                        elif key == '2':
                            con.sale()
                            input("按回车继续")
                        elif key == '3':
                            con.InShoper()
                            input("按回车继续")
                        elif key == '4':
                            con.Customer()
                            input("按回车继续")
                        elif key == '5':
                            con.CheckOut()
                            input("按回车继续")
                        elif key == '6':
                            con.record()
                            input("按回车继续")
                        elif key == '7':
                            con.Stock()
                            input("按回车继续")
                        elif key == '0':
                            exit_course = input('确定退出吗?(y/n):')
                            if exit_course == 'y' or exit_course=='Y':
                                exit()
                            else:
                                pass
                        else:
                            print("请输入正确的数值!")
                # 关闭游标,连接
                def close(self):
                    self.cursor.close()  # 关闭游标
                    self.connect.close()
            if __name__ == '__main__':
                con = database('127.0.0.1', 'zpx', '123', 'bookshop', '49680', 'utf8')
                # con.execute_sql("select * from 进货信息")
                # con.InShoper()
                # con.sale()
                # con.Customer()
                con.menu()