1.1课程设计选题
《家电销售订单管理系统》
1.2课程设计的目的
学生在充分理解《数据库应用》课程知识点的基础上,初步掌握将数据库应用于具体的管理信息系统中。把数据库原理、数据库应用有机的结合在一起,以数据库原理的理论为指导设计数据库,再将数据库设计应用到具体实例中。达到设计一个基本完整的后台数据库,并通过前台管理数据。
2 总体设计
2.1 功能需求
1.客户管理:能够管理客户信息,包括添加新客户、查看客户列表、编辑客户信息和删除客户等。
2.产品管理:能够管理家电产品信息,包括添加新家电(进货)、查看家电列表、编辑家电信息(修改家电信息)和删除家电等。
3.订单管理:能够创建新订单、查看订单列表、编辑订单信息和删除订单等。同时,需要能够查询特定订单、按日期范围或客户进行筛选,并能够生成订单报表。
4.库存管理:能够实时跟踪和管理库存信息,包括记录库存数量、更新库存状态等功能。将家电进货后,需要确定家电是否在库中已有,如果没有此类的家电信息,需要将家电的基本信息存入库中,并且添加入库的家电的数量;如果有相同的家电信息,则不需要录入家电信息,而直接更新家电的现有数量。
5.进货管理:能够记录和管理家电的进货信息,包括添加新的进货记录、查看进货列表、编辑进货信息和删除进货记录等。在进货过程中,需要记录进货日期、供应商信息、进货数量和进货价格等重要信息。
6.出库管理:能够记录和管理家电的出库信息,包括添加新的出库记录、查看出库列表、编辑出库信息和删除出库记录等。对于已经生成订单的家电要及时更新数据,对现有的家电数量进行更新检查,并且记录订单记录,以便为以后的进货作参考,如果家电售空,这可以提醒操作人员进货。
7.供应商管理:能够管理供应商信息,包括添加新供应商、查看供应商列表、编辑供应商信息和删除供应商等。并且对于供应商的联系方式要做出一定限制以便联系,如规定输入正确的手机号数,邮箱的正确形式。
8.登录功能:允许用户使用已注册的用户名和密码登录系统。登录过程需要验证用户输入的用户名和密码是否匹配,并且确保用户账号存在于数据库中。
9注册功能:允许新用户注册一个新的账号。注册过程需要收集用户的基本信息,如用户名、密码,并将这些信息保存到数据库中。
2.2 总体设计
本次课设实现的家电销售订单管理系统的功能设计如下:
1.进货管理——记录家电的进货信息。
2.家电管理——查看/上架家电
3.供应商管理——查看/新增供应商信息
4.会员管理——查看和新增会员信息
5.结账——完成历史进货和订单记录
6.进货和订单记录——查看历史进货和订单记录
7.库存容量——查看当前库存容量
8.家电订单统计——查看每种家电订单总数
9.订单管理——新增、修改和删除订单
10.进售管理——查看某段时间内各种家电的进货和订单情况
11.离开——退出程序
3数据库设计
3.1 数据库设计
我的家电销售订单管理系统采用关系型数据库模型,在用户观点下,关系模型中数据的逻辑结构是一张二维表,它由行和列组成。数据操作包括查询、插入、删除、更新,满足关系的完整性约束条件包括实体完整性、参照完整性、用户自定义完整性。
1、抽象出实体
根据数据库的需要,可以抽象出下面实体:
用户,供应商,订单,客户,家电,进货,库存
用户信息:(用户名,密码)
家电信息:(家电编号, 家电名称, 家电类别, 家电品牌, 家电价格, 家电重量)
客户信息:(客户号,客户姓名,客户性别,客户年龄,客户电话号码,客户邮箱)
供应商信息:(供应商号, 供应家电编号,供应商名称, 供应商电话号码,供应家电数量,供应商地址)
进货信息:(家电编号,进货单号,供应商号,图书进货数量,进货日期,家电类别)
订单信息 : (订单单号,订单日期, 家电名称,客户号,家电订单数量,订单金额)
库存信息: (家电编号, 家电类别,库存家电数量)
2、实体属性图和分E-R图
下面是各个实体的属性图,以及分E_R图
用户信息实体属性图
家电信息实体属性图
供应商信息实体属性图
进货信息实体属性图
客户信息实体属性图
订单信息实体属性图
库存信息实体属性图
订单分E-R图
进库分E-R图
入库分E-R图
出库分E-R图
全局总E-R图:
3.2 数据表设计
根据数据库的数据完整性设计原则,本次数据库系统一共包括 7个基本表,分别为用户信息表、家电信息表、客户信息表、供应商信息表、订单信息表、库存信息表、进货信息表,具体设计如下。
用户信息表:
create table 用户信息(
用户号 nchar(10) NOT NULL PRIMARY KEY,
密码 nchar(20) NOT NULL,
)
家电信息表
create table 家电信息(
家电编号 nchar(20) foreign key references 库存信息(家电编号),
家电名称 nchar(20) NOT NULL ,
家电类别 nchar(20) NOT NULL ,
家电品牌 nchar(20) NOT NULL,
家电价格 float check(家电价格>= 0),
家电重量 float not null
)
客户信息表
CREATE TABLE 客户信息(
客户号 nchar(10) NOT NULL PRIMARY KEY,
姓名 nchar(20) NOT NULL,
性别 nchar(20) NOT NULL,
年龄 int NOT NULL,
电话号码 nchar(20) UNIQUE,
邮箱 nchar(20) CHECK(邮箱 LIKE ‘_%@__%.%’)
);
供应商信息表
create table 供应商信息(
供应商号 nchar(10) NOT NULL PRIMARY KEY,
供应商名称 nchar(20) NOT NULL,
电话号码 nchar(20) NOT NULL,
供应商地址 nchar(40) NOT NULL,
供应家电编号 nchar(20)NOT NULL,
供应家电数量 int check(供应家电数量 >=0)
)
进货信息表
create table 进货信息(
进货单号 nchar(20) NOT NULL PRIMARY KEY,
家电编号 nchar(20) foreign key references 库存信息(家电编号),
家电类别 nchar(20) not NULL,
供应商号 nchar(10) foreign key references 供应商信息(供应商号),
家电进货数量 int NOT NULL,
进货日期 date default (getdate())
)
订单信息表
create table 订单信息(
订单单号 nchar(20) NOT NULL PRIMARY KEY,
家电编号 nchar(20) foreign key references 库存信息(家电编号),
客户号 nchar(10) foreign key references 客户信息(客户号),
家电订单数量 int NOT NULL,
订单日期 date default (getdate()),
订单金额 float null default (0)
)
库存信息表
create table 库存信息(
家电编号 nchar(20) PRIMARY KEY,
家电类别 nchar(20) not null,
家电数量 int check(家电数量>=0)
)
完整性约束:
–设置完整性约束
–设置订单金额默认值是0
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
3.3 视图设计
创建视图
create view zl_numb
as
select 家电类别,sum(家电数量) as 种类数量 from 库存信息 group by 家电类别
go
select * from zl_numb
create view ab1_numb
as
select 家电编号,sum(家电订单数量) as 家电订单总数
from 订单信息
group by 家电编号
go
select * from ab1_numb
3.4存储过程、函数设计
创建存储过程查询某段时间内各种图书的进货和销售情况;
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
3.5触发器设计
创建触发器当家电入库时自动修改相应家电的总量和存放仓库中该家电的数量
– 进货入库
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 库存增加(删除库存增加)
ALTER TABLE 进货信息
ADD CONSTRAINT 进货更新
FOREIGN KEY (家电编号)
REFERENCES 库存信息(家电编号)
ON UPDATE CASCADE;
–订单出库
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
修改前库存信息和进货信息:
下面进货2台家电编号为001的家电:
insert into 进货信息 (进货单号,家电编号,家电类别,供应商号,家电进货数量)values(‘a8’,‘001’,‘清洁家电’,‘03’,2)
修改后:
测试sql语句:
insert into 订单信息 (订单单号,家电编号,家电编号,家电订单数量,订单金额,订单日期)
values (‘b8’,‘001’,‘1’,2,’90.4’,’2023-04-23’)
当库存家电的数量为0时,会自动删除该库存信息家电信息。
– 自动填入金钱数量
create trigger 结账金额 on 订单信息 for insert as
declare @家电价格 float
declare @家电数量 int
declare @订单单号 nchar(10)
declare @家电编号 nchar(10)
declare @订单数量 int
select @订单数量=家电订单数量,@订单单号=订单单号,@家电编号=家电编号 from inserted
select @家电价格=家电价格 from 家电信息 where @家电编号=家电编号
update 订单信息 set 订单金额=@家电价格*@订单数量 where @订单单号=订单单号
Go
测试前销售信息
测试sql语句:
insert into 订单信息 (订单单号,家电编号,客户号,家电订单数量) values (‘b10’,‘001’,‘1’,2)
--客户性别进行约束
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 '年龄超出范围,必须在10-150岁之间!'
Rollback TRANSACTION
end
Go
测试sql语句
insert into 客户信息 values (‘5’,‘张三’,‘a’,30,‘1258468730’,‘233445453@qq.com’)
insert into 客户信息 values (‘6’,‘李四’,‘男’,9,‘1258468720’,’’)
3.6 安全性设计
用户标识:由用户名和用户标识号(密码)组成
为了确保系统的安全性和用户身份鉴别,设置登录和注册功能用于用户身份鉴别,给系统提供的最外层安全保护措施。(
用户登录和注册功能:实现用户身份验证的关键是要求用户提供有效的用户名和密码。
用户标识:每个用户都应被分配一个独一无二的用户标识号,通常是通过用户名和密码组成。确保用户标识号在系统整个生命周期内唯一,可以通过使用数据库的唯一约束来实现。
3.7 查询统计设计
基于索引物理结构,我们对数据库中每行数据添加了索引标识,其中最为常见的即为主键索引 Primary Key。在向数据库中添加数据例如建表的同时,我们创建主键索引,基于维护该数据索引,结合 SQL Server数据库管理系统的物理结构,在查询过程中产生了较好的优化效果。比如select 订单单号 from 订单信息
由于数据库管理系统的特性,WHERE 等数据操作遇到 null 值时会导致物理结构索引失效,导致引擎放弃使用索引而进行全表扫描。在优化层面,我们应该尽可能追求物理结构索引最大化发挥作用。因此,在每次数据操作时需要对数据字段进行 null 值判断,增加数据限制,如遇 null 值则及时返回,确保索引最大化程度使用。
4 数据应用设计
为了使数据库能够得到更加合理的运用,将其功能同实际联系起来,我用python高级程序语言写了前台,其中运用了嵌入式sql语言,有基本的增删查改功能,我使用的编程工具是pycharm 。
连接sql server数据库
首先需要导入pymssql库,pip install pymssql然后才能使用数据库操作的一些方法,同时也要在sql server中要建立一个可登录的用户,其中需要用到 pymssql.connect()方法,进行连接数据库,填入数据库访问地址(url),数据库的用户名和密码,还有数据库的名称,数据库的端口,这个默认是1433,但也有活动端口,最后还要写入读取的编码格式,防止乱码。
代码如下:
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
if name == ‘main’:
con = database(‘127.0.0.1’, ‘sa’, ‘123456’, ‘appliances’, ‘1433’, ‘utf8’)
con.menu()
增删查改功能
增删改功能是运用了pymssql .execute()和pymssql .commit() 方法,而查找则用pymssql .execute()和pymssql.fetchall()方法。都需要结合相关的内嵌式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(“\033[1;31m 输入sql语句错误!自动返回菜单!\033[0m”)
4.1 登录/注册设计
4.1.1 展示
注册
登录
4.2 进货设计
4.2.1 展示
4.3 查看/上架家电设计
4.3.1 展示
4.4 查看/新增供应商设计
4.4.1 展示
4.5 查看/新增会员设计
4.5.1 展示
4.6 结账设计
4.6.1 展示
4.7 查看进货和订单记录设计
4.7.1 展示
4.8 查看库存容量设计
4.8.1 展示
4.9 查看每种家电订单总数设计
4.9.1 展示
4.10 新增订单/删除订单/修改订单设计
4.10.1 展示
4.11 查看某段时间内各种家电的进货和订单情况设计
4.11.1 展示
4.12 退出设计
4.12.1 展示
5 小结和展望
这个课程设计花费了我不少的时间,遇到了诸多困难与压力,最终帮助我养成和提高了自学、纠错、测试等诸多能力。sql server学了一学期,从来没有这么透彻过,首先我对sql语言的各个部分都系统的串联了一遍,更加熟悉了触发器,级联操作,存储过程,约束条件,这些使得一些杂乱的数据变得井然有序。
其次在使用python实现内嵌式sql语言的时候,需要连接sql server ,这就需要自己动手去查找一些网上的资料,刚开始怎么也连不上,最后发现是端口的问题,连接上以后,又由于中文问题导致部分乱码,我整了一晚上才解决,是属性数据类型的问题,于是我改成了nchar类型的,它使用的是unicode编码,不会出现乱码的情况,于是我又学到了解决乱码的方法。每新增一个功能,我会先会只用数据库实现一遍再使用python语言通过面向函数编程来在控制台实现这个功能,虽然可能其中还会有其它问题但通过断点、print()以及报错信息让我都攻破了这些bug,完成了这次数据库课程设计!
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("\033[1;31m 输入sql语句错误!自动返回菜单!\033[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 + "','" + " )"
sql = "use appliances insert into 进货信息(进货单号,家电编号,家电类别,供应商号,家电进货数量) values ('" + num + "','" + bnum + "','" + kinds + "','" + inshopnum + "','" + snum + "')"
self.execute_sql(sql)
def sale(self):
chose=input("你是要查看,还是添加? C/A")
s = ''
s1 = ''
s2 = ''
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:
s2 += (str(k1).strip(' ')) + " "
print("已上架家电编号:")
if s2=='':
print("无")
print(s2)
sql = 'select 家电编号 from 库存信息'
self.cursor.execute(sql)
rows = self.cursor.fetchall()
for k in rows:
for k1 in k:
s1 += (str(k1).strip(' ')) + " "
print("库存内家电编号:")
if s1 == '':
print("无")
print(s1)
num = input("请输入要上架家电编号:")
bname = input("请输入家电名称:")
kinds = input("请输入家电类别:")
cbs = input("请输入家电品牌:")
price = input("请输入家电价格:")
ynum = input("请输入家电重量:")
#sql1 = "insert into 库存信息 values ('" + num + "','" + kinds + ynum + "')"
sql2 = "insert into 家电信息 values ('" + num + "','" + bname + "','" + kinds + "','" + cbs + "','" + price + "','" + ynum + "')"
print("正在上架...")
con.execute_sql(sql2)
if self.cursor.rowcount > 0:
print("上架成功")
else:
print("上架失败")
# try:
# self.cursor.execute(sql)
# self.connect.commit()
# print("上架成功")
# except Exception as e:
# print("上架失败",str(e))
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("请输入供应商地址:")
bianhao = input("请输入供应家电编号:")
shuliang = input("请输入供应家电数量:")
# sql=('insert into 供应商信息 values (%s,%s,%s,%s)'%(num,name,tel,add))
sql = "insert into 供应商信息 values ('" + num + "','" + name + "','" + tel + "','" + add + "','" + bianhao + "','" + shuliang + "')"
con.execute_sql(sql)
if self.cursor.rowcount > 0:
print("添加成功")
else:
print("添加失败")
chose='C'
elif chose=='c' or chose=='C':
s1 = ''
self.cursor.execute('select * from 供应商信息')
rows = self.cursor.fetchall()
print('现有供应商如下:')
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)
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("请输入客户性别:")
email = input("请输入客户邮箱:")
# sql=('insert into 供应商信息 values (%s,%s,%s,%s)'%(num,name,tel,add))
sql = "insert into 客户信息 values ('" + num + "','" + name + "','" + sex + "','" + age + "','" + tel + "','" + email + "')"
# print(sql)
con.execute_sql(sql)
# if self.cursor.rowcount > 0:
# print("添加成功")
# else:
# print("添加失败")
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客户电话\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)#self.cursor 表示数据库连接对象的游标,execute() 方法用于执行指定的 SQL 语句。
rows = self.cursor.fetchall()#self.cursor 表示数据库连接对象的游标,fetchall() 方法用于获取查询结果的所有行
#con.execute_sql(sql) # 执行该sql语句对数据库进行操作
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("请输入订单家电数量:")
dateding = input("请输入订单日期:")
#sql=('insert into 供应商信息 values (%s,%s,%s,%s)'%(num,name,tel,add))
sql = "insert into 订单信息(订单单号,家电编号,客户号,家电订单数量,订单日期) values ('" + num + "','" + name + "','" + uname + "','" + add + "','" + dateding + "')"
# print(sql)
con.execute_sql(sql)#执行该sql语句对数据库进行操作
s1 = ''
try:
sql = "select 订单金额 from 订单信息 where 订单单号= '"+num+"'"
self.cursor.execute(sql)
rows = self.cursor.fetchall()
for k in rows:
for k1 in k:
s1 = (str(k1).strip(' '))
if s1:
print("应付金额 :" + s1)
else:
print("未找到订单金额")
except:
print("sql语句错误!")
# for k in rows:
# for k1 in k:
# s1=(str(k1).strip(' '))
# if s1:
# print("应付金额 :"+s1)
# else:
# print("未找到订单金额")
#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)
elif 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 zl_numb'
# # 执行查询
# cursor.execute('SELECT * FROM zl_numb')
#
# # 获取查询结果
# rows = cursor.fetchall()
# # 遍历结果并打印输出
# for row in rows:
# print(row)
self.cursor.execute(sql)
rows = self.cursor.fetchall()
print("家电类别 \t种类数量")
for k in rows:
for k1 in k:
s1 += (str(k1).strip(' ')) + "\t\t"
s1 += '\n'
if s1 == '':
print("无")
print(s1)
def dingdansum(self):
s1 = ''
new_view_def = """
CREATE VIEW ab1_numb AS
SELECT 家电编号, SUM(家电订单数量) AS 家电订单总数
FROM 订单信息
GROUP BY 家电编号;
"""
self.cursor.execute("DROP VIEW IF EXISTS ab1_numb")
# 创建新视图
self.cursor.execute(new_view_def)
sql = 'select * from ab1_numb'
self.cursor.execute(sql)
rows = self.cursor.fetchall()
print("家电编号\t\t家电订单总数")
for k in rows:
for k1 in k:
s1 += (str(k1).strip(' ')) + "\t\t"
s1 += '\n'
if s1 == '':
print("无")
print(s1)
def ordermanagement(self):
chose = input("你是要添加订单,还是修改订单,还是删除订单? A/G/D:")
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("请输入增加的订单单号:")
bnum = input("请输入增加的家电编号:")
unum = input("请输入增加的客户号:")
dnum = input("请输入增加的家电订单数量: ")
date = input("请输入增加的订单日期:")
money = input("请输入增加的订单金额:")
# sql=('insert into 供应商信息 values (%s,%s,%s,%s)'%(num,name,tel,add))
sql = "insert into 订单信息 values ('" + num + "','" + bnum + "','" + unum + "','" + dnum + "','" + date + "','" + money + "')"
#sql = "insert into 订单信息 values ('" + num + "','" + bnum + "','" + unum + "','" + dnum + "','" + date + "')"
# print(sql)
con.execute_sql(sql)
elif chose == 'g' or chose == 'G':
s1 = ''
gknum = input("请输入要修改的订单单号:")
bnum = input("请输入新的家电编号:")
unum = input("请输入新的客户号:")
dnum = input("请输入新的家电订单数量: ")
date = input("请输入新的订单日期:")
money = input("请输入新的订单金额:")
update_sql = "UPDATE 订单信息 SET 家电编号 = '" + bnum + "', 客户号 = '" + unum + "', 家电订单数量 = '" + dnum + "', 订单日期 = '" + date + "', 订单金额 = '" + money + "' WHERE 订单单号 = '" + gknum + "'"
con.execute_sql(update_sql)
#print("订单信息已更新")
if con.cursor.rowcount > 0:
print("订单信息已更新")
print("修改后的订单信息为:")
sql = "select * from 订单信息 where 订单单号= '" + gknum + "'"
result = con.execute_sql(sql)
#print("修改后的订单信息为:")
# self.cursor.execute(sql)
# row = self.cursor.fetchall()
else:
print("未找到要修改的订单信息")
elif chose == 'd' or chose == 'D':
s1 = ''
gknum = input("请输入要删除的订单单号:")
sql = "delete from 订单信息 where 订单单号= '" + gknum + "'"
con.execute_sql(sql)
# print("订单信息已删除")
if self.cursor.rowcount > 0:
print("订单信息已删除")
else:
print("未找到要删除的订单信息")
# 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("输入有误,请重新输入!")
# self.cursor.execute(sql) # self.cursor 表示数据库连接对象的游标,execute() 方法用于执行指定的 SQL 语句。
# rows = self.cursor.fetchall() # self.cursor 表示数据库连接对象的游标,fetchall() 方法用于获取查询结果的所有行
#
# con.execute_sql(sql) # 执行该sql语句对数据库进行操作
def login(self):
chose = input("你是要登录or注册?L/Z")
if chose == 'L' or chose == 'l':
a1 = ''
usernum1 = input("请输入账号:")
password1 = input("请输入密码:")
select22_sql = "SELECT 密码 FROM 用户信息 WHERE 用户号 = '" + usernum1 + "'"
self.cursor.execute(select22_sql)
result = self.cursor.fetchall()
# print(result)
# if password1.strip() in [result[0].strip() for result in result]:
if result and password1.strip() == result[0][0].strip():
print("登录成功!")
return True
else:
print("登录失败!")
print("用户名或密码错误!")
return False
# elif chose == 'Z' or chose == 'z':
# ss2 = ''
# usernum2 = input("请输入账号:")
# password2 = input("请输入密码:")
# sql = "insert into 用户信息 values ('" + usernum2 + "','" + password2 + "')"
#
# # sql = "INSERT INTO 用户信息 values (?, ?)"
# #self.cursor.execute(sql, (usernum, password))
# #print("注册成功!")
# try:
# self.cursor.execute(sql)
# print("注册成功!")
# usernum1 = input("请输入账号:")
# password1 = input("请输入密码:")
# select22_sql = "SELECT 密码 FROM 用户信息 WHERE 用户号 = '" + usernum1 + "'"
# self.cursor.execute(select22_sql)
# result = self.cursor.fetchall()
# # print(result)
# # if password1.strip() in [result[0].strip() for result in result]:
# if password1.strip() == result[0][0].strip():
# print("登录成功!")
# return True
# else:
# print("登录失败!")
# print("用户名或密码错误!")
# return False
# except Exception as e:
# print("注册失败!", str(e))
elif chose == 'Z' or chose == 'z':
while True:
usernum2 = input("请输入账号:")
password2 = input("请输入密码:")
check_sql = "SELECT * FROM 用户信息 WHERE 用户号 = %s"
self.cursor.execute(check_sql, (usernum2,))
result = self.cursor.fetchone()
if result:
print("该账号已被注册,请重新输入!")
else:
insert_sql = " use appliances INSERT INTO 用户信息 values (%s, %s)"
self.cursor.execute(insert_sql, (usernum2, password2))
# self.connection.commit()
print("注册成功!")
# 跳转到登录
while True:
usernum3 = input("请输入账号:")
password3 = input("请输入密码:")
select_sql = "SELECT 密码 FROM 用户信息 WHERE 用户号 = %s"
self.cursor.execute(select_sql, (usernum3,))
result2 = self.cursor.fetchone()
print(result2)
print(password3.strip())
print(result2[0][0].strip())
if password3.strip() == result2[0].strip():
print("登录成功!")
return True
else:
print("登录失败!用户名或密码错误")
def storage(self):
s1 = ''
s2 = ''
date1 = input("输入第一个日期:")
date2 = input("输入第二个日期:")
print("")
sql = "exec 进售信息 '" + date1 + "','" + date2 + "'"
self.cursor.execute(sql)
# rows = self.cursor.fetchall()
# print(rows)
# for row in rows:
# # 处理每一行数据,例如将数据转换成字符串并打印出来
# s1 += str(row) + '\n'
# #print(s1)
# 获取所有查询结果
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'
print(s1)
# 切换到下一个结果集
print("订单单号\t家电编号\t 客户号\t家电销售数量\t订单日期\t\t 订单金额")
while self.cursor.nextset():
# 获取下一个查询结果
rows = self.cursor.fetchall()
for k in rows:
for k2 in k:
s2 += (str(k2).strip(' ')) + "\t\t"
s2 += '\n'
print(s2)
def menu(self):
print("欢迎来到家电销售订单管理系统!")
while con.login():
while True:
print("服务菜单如下:")
print('1.进货')
print('2.查看/上架家电')
print('3.查看/新增供应商')
print('4.查看/新增会员')
print('5.结账')
print('6.查看进货和订单记录')
print('7.查看库存容量')
print('8.查看每种家电订单总数')
print('9.新增订单/删除订单/修改订单')
print('10.查看某段时间内各种家电的进货和订单情况')
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 == '8':
con.dingdansum()
input("按回车继续")
elif key == '9':
con.ordermanagement()
input("按回车继续")
elif key == '10':
con.storage()
input("按回车继续")
elif key == '0':
exit_course = input('确定退出吗?(y/n):')
if exit_course == 'y' or exit_course == 'Y':
exit()
else:
pass
else:
print("输入有误,请输入正确的数值!")
else:
print("请先登录")
# 关闭游标,连接
def close(self):
self.cursor.close() # 关闭游标
self.connect.close()
if __name__ == '__main__':
con = database('127.0.0.1', 'sa', '123456', 'appliances', '1433', 'utf8')
# con.execute_sql("select * from 进货信息")
# con.InShoper()
# con.sale()
# con.Customer()
con.menu()
数据库代码:
create database goods_management
on
( name='appliance_management_m',
filename='d:\\appliance_management_m.mdf',
size=30mb,
filegrowth=10%,
maxsize=unlimited),
( name='appliance_management_n',
filename='d:\\appliance_management_n.ndf',
size=20mb,
filegrowth=2mb,
maxsize=unlimited)
log on
( name='appliance_management_l',
filename='d:\\appliance_management_l.ldf',
size=10mb,
filegrowth=5mb,
maxsize=unlimited)
go
create table 用户信息(
用户号 nchar(10) NOT NULL PRIMARY KEY,
密码 nchar(20) NOT NULL,
)
create table 家电信息(
家电编号 nchar(20) foreign key references 库存信息(家电编号),
家电名称 nchar(20) NOT NULL ,
家电类别 nchar(20) NOT NULL ,
家电品牌 nchar(20) NOT NULL,
家电价格 float check(家电价格>= 0),
家电重量 float not null
)
CREATE TABLE 客户信息(
客户号 nchar(10) NOT NULL PRIMARY KEY,
姓名 nchar(20) NOT NULL,
性别 nchar(20) NOT NULL,
年龄 int NOT NULL,
电话号码 nchar(20) UNIQUE,
邮箱 nchar(20) CHECK(邮箱 LIKE '_%@__%.%')
);
create table 供应商信息(
供应商号 nchar(10) NOT NULL PRIMARY KEY,
供应商名称 nchar(20) NOT NULL,
电话号码 nchar(20) NOT NULL,
供应商地址 nchar(40) NOT NULL,
供应家电编号 nchar(20)NOT NULL,
供应家电数量 int check(供应家电数量 >=0)
)
create table 进货信息(
进货单号 nchar(20) NOT NULL PRIMARY KEY,
家电编号 nchar(20) foreign key references 库存信息(家电编号),
家电类别 nchar(20) not NULL,
供应商号 nchar(10) foreign key references 供应商信息(供应商号),
家电进货数量 int NOT NULL,
进货日期 date default (getdate())
)
create table 订单信息(
订单单号 nchar(20) NOT NULL PRIMARY KEY,
家电编号 nchar(20) foreign key references 库存信息(家电编号),
客户号 nchar(10) foreign key references 客户信息(客户号),
家电订单数量 int NOT NULL,
订单日期 date default (getdate()),
订单金额 float null default (0)
)
create table 库存信息(
家电编号 nchar(20) PRIMARY KEY,
家电类别 nchar(20) not null,
家电数量 int check(家电数量>=0)
)
添加数据:
insert into 用户信息 values ('admin','123456')
insert into 用户信息 values ('123','123')
select* from 用户信息
insert into 家电信息 values ('001','洗衣机','清洁家电','美的',45.2,15000)
insert into 家电信息 values ('002','冰箱','厨房家电','戴尔',30.0,144440)
insert into 家电信息 values ('003','电视','生活家电','松下',45.5,6540)
insert into 家电信息 values ('004','空调','生活家电','海尔',30.1,1345540)
insert into 家电信息 values ('005','打印机','办公家电','晨光',30.1,242540)
insert into 家电信息 values ('006','电动牙刷','健康护理家电','飞利浦',30.1,540)
select * from 家电信息
--delete
--from 家电信息
--where 家电编号 = '007'
insert into 客户信息 values
('1','王壮','男',30,'1258468720',’123423132@qq.com’),
('2','张力','男',35,'1845846872',’923711323@qq.com’),
('3','马超','男',20,'5896668720',’771316775@qq.com’),
('4','小红','女',18,'1598468720',’283772636@qq.com’)
select * from 客户信息
insert into 客户信息 values
('6','王小壮','男',30,'1258468720',’27361936@qq.com’)
insert into 供应商信息 values
('01','好再来','5265655','爱德华学院批发',’001’,90),
('02','德利','5265655','深度DJ东山家电',’002’,87),
('03','阿豪家电','5265655','上海智能家居',’003’,67),
('04','建德HD','5265655','碧水卡德加家电',’004’,66)
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',20)
insert into 进货信息 (进货单号,家电编号,家电类别,供应商号,家电进货数量)values('a5','004','生活家电','02',20)
select * from 进货信息
insert into 订单信息 (订单单号,家电编号,客户号,家电订单数量,订单日期,订单金额) values ('b2','001','1',2,’2023-01-01’,1000)
insert into 订单信息 (订单单号,家电编号,客户号,家电订单数量,订单日期,订单金额) values ('b1','003','2',20,’2024-01-08’,8888)
select * from 订单信息
delete from 订单信息
insert into 库存信息 values ('001','清洁家电',10)
insert into 库存信息 values ('002','厨房家电',20)
insert into 库存信息 values ('003','生活家电',20)
insert into 库存信息 values ('004','生活家电',20)
insert into 库存信息 values ('005','办公家电',20)
insert into 库存信息 values ('006','健康护理家电',20)
select * from 库存信息
delete 库存信息 where 书号='003'
Delete 订单信息 where 订单单号=’1’
use appliances
delete from 家电信息 WHERE 家电名称 = '电饭煲';
select * from 家电信息
-- 存储过程设置
--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
--2. 创建视图查询每种家电的订单总数;
create view ab1_numb
as
select 家电编号,sum(家电订单数量) as 家电订单总数
from 订单信息
group by 家电编号
go
select * from ab1_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 库存增加(删除库存增加)
ALTER TABLE 进货信息
ADD CONSTRAINT 进货更新
FOREIGN KEY (家电编号)
REFERENCES 库存信息(家电编号)
ON UPDATE CASCADE;
--订单出库
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)
declare @订单数量 int
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 '年龄超出范围,必须在10-150岁之间!'
Rollback TRANSACTION
end
go
完整性约束:
--设置完整性约束
--设置订单金额默认值是0
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