《数据库原理及应用》药店药品进销存管理系统
1.课程设计目的 |
(1)培养学生运用所学课程《数据库原理及应用》的理论知识和技能,深入理解《数据库原理及应用》课程相关的理论知识,学会分析实际问题的能力。 (2)培养学生掌握用《数据库原理及应用》的知识设计计算机应用课题的思想和方法。 (3)培养学生调查研究、查阅技术文献、资料、手册以及编写技术文献的能力。 (4)通过课程设计的训练,要求学生在教师的指导下,独立完成大作业要求的相关内容,包括: ① 通过调查研究和运用Internet,收集和调查有关资料、最新技术信息。 ② 基本掌握撰写小论文的基本步骤和写作方法。 ③ 根据课题的要求基本理解和掌握E-R图的设计方法和关系模式的转换。 ④ 根据课题的要求基本理解和掌握数据流图(DFD)和数据字典(DD)的设计方法。 ⑤ 根据E-R图生成关系模型,并进面生成数据库表。 实现数据库完整性、安全性保证措施。 实现数据库系统、维护计划。 |
2.课程设计任务与要求 |
(1)每个学生从下面50个题目中任选一个作为课程设计,调查分析一个具体的或模拟的实例。; (2)描述该实例的业务信息和管理工作的要求,画出业务流图、数据流图,确定数据字典; (3)列出实体、联系; (4)指出实体和联系的属性; (5)画出E-R图; (6)将E-R图转换成关系模式,并注明主码和外码; (7)创建数据库; (8)根据题目的要求写查询、存储过程、触发器等; (9)系统实现; |
3.课程设计说明书 |
3.1 需求分析 3.1.1 功能需求 本系统需要实现的功能具体如下: 1) 登录管理:由于是限定药店工作人员使用,登录功能可选择管理员登录或者员工登录,登录功能里有注册和修改密码设置,用户登录时,只有将用户名和密码输入后,才能够使登录按钮有效,输入后会提示密码的对错。如果密码正确,提示登录成功后直接进入系统;密码错误,则提示用户名或密码错误,要求重新输入; 2) 用户管理:管理员登陆后可以编辑修改个人信息。可根据条件检索药品信息,修改药品类型、厂商的管理。员工登陆后可编辑个人资料,完善个人信息,校检用户信息是否符合规范。 3) 药品信息管理模块:第一是上架管理功能,管理员可以对上架的药品进行管理,在药品上架的时候把上架信息记录下来留作依据。如果上架药品需要修改的,可以在上架单列表中把单子选中出来进行修改,甚至删除。方便药品上架时的更改需要。第二是下架管理功能,管理员可以对过期的药品进行管理,在药品过期的时候把过期信息记录下来留作依据。如果下架架药品需要修改的,可以在下架单列表中把单子选中出来进行修改,甚至删除。方便药品下架时的更改需要。第三是药品信息查询统计,对药品上架信息按照选择的查询条件进行查询,而且能够按照统计条件进行统计并以直观的图形和列表形式显示。 4) 采购管理:管理员可选择库存少的药品进行采购,进货订单可实现退货,同时可选择购买的数量、进货金额、生产厂商等。对每日库存量进行信息汇总。库存信息一目了然。 5) 销售管理:管理员需要管理所有的销售单。并以列表的形式显示出来;该功能要实现添加销售单,完成药品销售。其次,实现药品销售查询统计,对药品销售信息按照选择的查询条件进行查询,并能够对查询的结果用表形式显示出来。生成每日收款日报,实现销售药品时,计算总计金额,并可选择销售数量。 6) 库存管理:销售完成的同时,库存也相应减少,管理员可自助查询每种药品的库存量。 7) 信息管理:可对药品id进行查询,实现快速检索信息,药品信息的增加、删除; 3.1.2 数据需求 进销存系统的数据需求包括如下几点: 1)数据录入和处理的准确性和实时性 数据的输入是否准确是数据处理的前提,错误的输入会导致系统无法正常识别进而导致输出的不正确,从而是系统的工作失去意义。数据的输入来源是手工输入。手工输入要通过系统界面上的安排系统具有容错性。 在系统中,数据的输入往往是大量的,因此系统要有一定的处理能力,以保证迅速的处理数据。 2)数据的一致性与完整性 由于系统的数据是共享的,在不同的客户端中,商品数据是共享数据,所以如何保证这些数据的一致性,是系统必须解决的问题。要解决这一问题,要有后台数据库的支持。 3)数据的共享与独立性 进销存系统的数据是共享的。然而,从系统开发的角度上看,共享会给设计和调试带来困难。因此,应该提供灵活的配置,使各个分系统能够独立运行,通过人工干预的手段进行系统数据的交换。这样,也能提供系统的强壮性。 3.1.3 数据流图 图3.1.1 顶层数据流图 图3.1.2 0层数据流图 图3.1.3 1号数据流图 图3.1.4 2号数据流图 图3.1.5 3号数据流图 3.1.4 数据字典 3.1.4.1数据流图条目 登陆 = [仓库管理员|员工|管理员] 员工信息 = 员工编号 仓库管理员 = 员工编号+员工类型 管理员 = 员工编号+员工类型 药品信息 = 药品编号+药品名称+药品类型+生产厂商 进货信息 = 药品编号+进货单价+进货数量+进货日期 销售信息 = 药品编号+销售价+销售数量+销售日期 入库单 = 药品编号+入库数量+入库时间+ 员工编号 出库单 = 药品编号+出库数量+出库时间+ 员工编号 库存信息 = 药品编号+药品名称+药品类型+生产厂商+库存量 库存统计表 = 药品编号+药品名称+药品类型+生产厂商+库存量 3.1.4.2 数据文件条目 文件名:管理员信息文件 数据组成:{员工编号+员工姓名+员工性别+员工类型++员工用户名+员工密码 } 数据组织:按员工编号递增排列 文件名:库存文件 数据组成:{药品编号+药品名称+药品类型+生产厂商+库存量+库存状态} 数据组织:按药品编号递增排列 文件名:销售信息文件 数据组成:{药品编号+销售价+销售数量+销售日期} 数据组织:按药品编号递增排列 文件名:进货信息文件 数据组成:{药品编号+进货单价+进货数量+进货日期} 数据组织:按药品编号递增排列 3.1.4.3 数据项条目 员工编号 = U 表示整型的自增序列 员工姓名 = V(20) 表示长度为20的字符串 员工性别 = V(10) 表示长度为10的字符串 员工类型 = V(20) 表示长度为20的字符串 = V(20) 表示长度为20的字符串 员工用户名 = V(20) 表示长度为20的字符串 员工密码 = V(20) 表示长度为20的字符串 药品编号 = U 表示整型的自增序列 药品名称 = V(20) 表示长度为20的字符串 药品类型 = V(20) 表示长度为20的字符串 生产厂商 = V(20) 表示长度为20的字符串 库存量 = I 表示为整型的正整数 库存状态 = V(10) 表示长度为10的字符串 销售价 = N(5,2) 表示长度为5,小数位为2位的实数 销售数量 = I 表示为整型的正整数 销售日期 = D(8) 表示长度为8的日期类型 进货单价 = N(5,2) 表示长度为5,小数位为2位的实数 进货数量 = I 表示为整型的正整数 进货日期 = D(8) 表示长度为8的日期类型 3.1.4.4 加工条目 加工编号:1 加工名称:登陆管理 加工功能:根据管理员信息文件中的员工用户名和密码登陆跳转到后台查看员工信息、库存信息根据员工编号确定员工身份,仓库管理人员跳转到仓库管理界面。 加工编号:2.1 加工名称:库存管理 加工功能:当仓库管理人员收到管理员发来的入库单和药品,系统将会自动增加库存。当仓库管理人员收到售药员工给的出库单,系统将会减少相应药品库存。 加工编号:2.2 加工名称:库存统计 加工功能:系统自动查询库存信息,并将其进行统计。 加工编号:3.1 加工名称:售药面板 加工功能:员工可以按条件查药品,并选择售出数量,此时该订单生成并记录到销售信息表中,同时库存中,该药品数量相应减少。 加工编号:3.2 加工名称:出库验收 加工功能:仓库管理员收到销售信息表,将所需药品记录出库并生成出库单。 加工编号:4 加工名称:进货面板 加工功能:当库存缺少某种药品,将提示药品库存状态“紧缺”,此时管理员根据库存数量和状态对药品进货。 3.1.5 数据库完整性 数据库完整性(Database Integrity)是指数据库中数据在逻辑上的一致性、正确性、有效性和相容性。它是应防止数据库中存在不符合语义规定的数据和防止因错误信息的输入输出造成无效操作或错误信息而提出的。数据库完整性由各种各样的完整性约束来保证,因此可以说数据库完整性设计就是数据库完整性约束的设计。。本系统主要通过外键来保证数据库的完整性,任何两个有关联关系的数据库表都必须设定外键,以防止缺少必要数据的情况发生。 3.2 数据库设计 3.2.1 概念模型设计 3.2.1.1局部E-R图 员工和药品 药品和仓库 全局E-R图 3.2.2 逻辑模型设计 仓库(仓库号,仓库名) 药品(药品编号,名称,类型,生产厂商) 入库(仓库号,药品编号,入库数量,入库时间) 外键:仓库号,药品编号 出库(仓库号,药品编号,出库数量,出库时间) 外键:仓库号,药品编号 员工(员工编号,员工姓名,员工性别,员工类型,员工电话) 进货(员工编号,仓库号,药品编号,进货单价,进货数量,进货日期)外键:员工编号,仓库号,药品编号 销售(员工编号,仓库号,药品编号,销售价,销售数量,销售日期)外键:员工编号,仓库号,药品编号 3.2.3 数据库实现 --创建数据库yaodian create database yaodian on ( name=yaodian _Data, filename='D:\yaodianData.mdf', size=10, maxsize=500, filegrowth=10) log on ( name=yaodian_Log, filename='D:\ yaodian.ldf', size=5, maxsize=500, filegrowth=5) --创建数据表及约束 use yaodian go --创建员工表 create table S ( 员工编号 char(10) not null primary key, 员工姓名 char(20) not null, 员工性别 char(2) not null, 员工类型 char(20) not null primary key, char(20) not null, 员工用户名 char(20)not null, 员工密码 char(20)not null ) Go --创建仓库表 create table D ( 仓库号 char(10) not null primary key, 仓库名 char(20) not null ) go --创建药品信息表 create table A ( 药品编号 char(10) not null primary key, 药品名称 char(20) not null, 药品类型 char(20) not null, 生产厂商 char(20) not null) Go --创建库存表 Create table AD ( 仓库号 char(10)not null foreign key references D(仓库号), 药品编号 char(10) not null foreign key references A(药品编号), 药品名称char(20) not null, 药品类型 char(20) not null, 生产厂商 char(20) not null, 药品数量 int not null) Go --入库信息表 create table B ( 仓库号 char(4) not null foreign key references D(仓库号), 药品编号 char(10) not null foreign key references A(药品编号), 入库数量 int not null , 入库日期 char(10) not null, constraint B_prim primary key(仓库号,药品编号)) go --出库信息表 create table C ( 仓库号 char(4) not null foreign key references D(仓库号), 药品编号 char(10) not null foreign key references A(药品编号), 出库数量 int not null , 出库日期 char(10) not null, constraint C_prim primary key(仓库号,药品编号)) go --药品进货表 create table ioD ( 员工编号 int not null foreign key references S(员工编号), 药品编号 char(10) not null foreign key references A(药品编号), 仓库号 char(10) not null foreign key references D(仓库号), 进货单价 char(10) not null, 进货数量 int not null, 进货日期 datetime default (getdate()) not null, constraint ioD_Prim primary key(员工编号,药品编号,仓库号)) --销售信息表 create table RD ( 员工编号 int not null foreign key references S(员工编号), 药品编号 char(10) not null foreign key references A(药品编号), 仓库号 char(10) not null foreign key references D(仓库号), 销售价 char(10) not null, 销售数量 int not null, 销售日期 datetime default (getdate()) not null, constraint RD_Prim primary key(员工编号,药品编号,仓库号)) 3.2.4 系统使用的技术 触发器 /*创建触发器,实现药品入库药品库存的自动更新;*/ --插入触发器 use yaodian go create trigger insert_AD on AD after insert as declare @ano char(10),@dno char(10),@num int select @ano=药品名称,@dno=仓库号,@num=药品数量 from inserted if not exists(select 药品名称 from A where 药品名称=@ano) begin print '不存在'+@ano+'药品不能入库!'rollback end else if not exists(select 仓库号 from D where 仓库号=@dno) begin print '不存在'+@dno+'仓库药品不能入库!'rollback end else begin insert into ioD(药品名称,仓库号,出入库药品数量,出入标志1入0出) values(@ano,@dno,@num,1) print @ano+'药品入库! 仓库:'+@dno+'数量:'+convert(varchar(10),@num) end --更新触发器 go create trigger update_AD on AD after update as declare @ano1 char(10),@dno1 char(10),@num1 int, @ano2 char(10),@dno2 char(10),@num2 int select @ano1=药品名称,@dno1=仓库号,@num1=药品数量 from deleted select @ano2=药品名称,@dno2=仓库号,@num2=药品数量 from inserted if(@ano1=@ano2 and @dno1=@dno2) begin if(@num1>@num2) begin insert into ioD(药品名称,仓库号,出入库药品数量,出入标志1入0出) values(@ano1,@dno1,@num1-@num2,0) print @ano1+'药品出库!仓库:'+@dno1+'数量:'+convert(varchar(10),@num1-@num2) end else begin insert into ioD(药品名称,仓库号,出入库药品数量,出入标志1入0出) values(@ano2,@dno2,@num2-@num1,1) print @ano1+'药品入库!仓库:'+@dno1+'数量:'+convert(varchar(10),@num2-@num1) end end else if not exists(select 药品名称 from A where 药品名称=@ano2) begin print '不存在'+@ano2+'药品,修改错误!' rollback end else if not exists(select 仓库号 from D where 仓库号=@dno2) begin print '不存在'+@dno2+'仓库药品,修改错误!' rollback end else begin insert into ioD(药品名称,仓库号,出入库药品数量,出入标志1入0出) values(@ano1,@dno1,@num1,0) print @ano1+'药品出库!仓库:'+@dno1+'数量:'+convert(varchar(10),@num1) insert into ioD(药品名称,仓库号,出入库药品数量,出入标志1入0出) values(@ano2,@dno2,@num2,1) print @ano2+'药品入库!仓库:'+@dno1+'数量:'+convert(varchar(10),@num2) end --删除触发器 go create trigger delete_AD on AD after delete as declare @ano char(10),@dno char(10),@num int select @ano=药品名称,@dno=仓库号,@num=药品数量 from deleted insert into ioD(药品名称,仓库号,出入库药品数量,出入标志1入0出) values(@ano,@dno,@num,0) print @ano+'药品销毁!\n仓库:'+@dno+'数量:'+convert(varchar(10),@num) /*创建触发器,实现转仓时转入仓库药品增加、转出仓库药品减少*/ --插入触发器 go create trigger insert_RD on RD after insert as declare @ano char(10),@dno1 char(10),@dno2 char(10),@remnum int select @ano=药品名称,@dno1=转出仓库号,@dno2=转入仓库号,@remnum=转仓数量 from insertedforeign key references用法 if(@dno1=@dno2) begin print '相同仓库不能转库!'rollback end else if (select 药品数量 from AD where 仓库号=@dno1 and 药品名称=@ano)<@remnum begin print @ano+'药品转库数量不足!'rollback end else begin update AD set 药品数量=药品数量-@remnum where 药品名称=@ano and 仓库号=@dno1 if exists(select 药品名称 from AD where 药品名称=@ano and 仓库号=@dno2) update AD set 药品数量=药品数量+@remnum where 药品名称=@ano and 仓库号=@dno2 else insert into AD(仓库号,药品名称,药品数量) values(@dno2,@ano,@remnum) print @ano+'药品转库成功!转出仓库:'+@dno1+'转入仓库:'+@dno2+'数量:'+convert(varchar(10),@remnum) end --更新触发器 go create trigger update_RD on RD instead of update as print '禁止对此表进行修改操作!' rollback ---将对表全部锁定禁止操作 --删除触发器 go create trigger delete_RD on RD after delete as print '禁止对此表进行修改操作!' rollback ---将对表全部锁定禁止操作 存储过程 /*创建存储过程统计各仓库各种药品的现存数量;*/ use MEDIC --统计各仓库各种药品的现存数量 go create procedure findAD as select D.仓库名 as 仓库名,A.药品名 as 药品名,药品数量 as 现存数量 from AD,A,D where AD.药品名称=A.药品名称 and AD.仓库号=D.仓库号 --查询某仓库各种药品存储情况 go create procedure findAD_D ( @dno char(10)) as select D.仓库名 as 仓库名,A.药品名 as 药品名,药品数量 as 现存数量 from AD,A,D where AD.药品名称=A.药品名称 and AD.仓库号=D.仓库号 and AD.仓库号=@dno ----查询各仓库某种类型药品存储情况 go create procedure findAclass (@class char(20)) as select D.仓库名 as 仓库名,A.药品名 as 药品名,药品类型 as 类型,药品数量 as 现存数量 from AD,A,D where AD.药品名称=A.药品名称 and AD.仓库号=D.仓库号 and 药品类型=@class /*创建存储过程统计指定时间段内各种药品的入库数量和领用数量;*/ go --指定时间段内各种药品的入库数量 create procedure findTime (@time1 datetime, @time2 datetime) as select 仓库名 as 仓库名,药品名 as 药品名称,出入库药品数量 as 入库数量,出入库时间 as 入库时间 from ioD,A,D where 出入库时间 between @time1 and @time2 and 出入标志1入0出=1 and ioD.药品名称=A.药品名称 and ioD.仓库号=D.仓库号 go --指定时间段内各种药品的领用数量 create procedure findGettime (@time1 datetime, @time2 datetime) as select 员工姓名 as 领取人,药品名 as 药品名,仓库名 as 仓库名,领取数量 as 领取数量,领取时间 as 领取时间 from SA,A,D,S where 领取时间 between @time1 and @time2 and SA.员工号=S.员工号 and SA.药品名称=A.药品名称 and SA.仓库号=D.仓库号 3.3 系统设计 3.3.1 系统功能结构 药品管理: ●药品信息 ●药品入库 ●药品出库 仓库管理: ●仓库列表 ●入库记录 ●库存统计 ●出库记录 ●仓库管理员列表 员工管理: ●员工列表 ●管理员列表 ●仓库管理员列表 3.3.2 关键代码 //数据库连接 void init() { JLabel label = new JLabel("欢迎进入药店管理系统!"); JLabel labUsername = new JLabel("用户名"); JLabel labPassword = new JLabel("密码"); JTextField username = new JTextField(20); JPasswordField password = new JPasswordField(20); JButton btn1 = new JButton("登录"); add(label); add(labUsername); add(username); add(labPassword); add(password); add(btn1); label.setBounds(220, 40, 360, 75); labUsername.setBounds(260, 150, 60, 40); labPassword.setBounds(265, 220, 60, 40); username.setBounds(320, 150, 180, 40); password.setBounds(320, 220, 180, 40); btn1.setBounds(320, 290, 180, 30); label.setFont(new Font("微软雅黑", Font.BOLD, 30)); btn1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (username.getText().trim().length() == 0 || new String(password.getPassword()).trim().length() == 0) JOptionPane.showMessageDialog(null, "用户名密码不允许为空"); else { Connection con = SqlOperation.getConnection(); Statement statement = null; try { statement = con.createStatement(); } catch (SQLException e2) { e2.printStackTrace(); } String sql = "SELECT * FROM ID WHERE IDUsername=" + username.getText().trim() + " AND IDPassword=" + new String(password.getPassword()).trim(); try { assert statement != null; ResultSet rs = uteQuery(sql); while (rs.next()) { Enter.IDName = rs.getString("IDName"); JOptionPane.showMessageDialog(null,"欢迎使用本系统,"+Enter.IDName); int IDFlag =rs.getInt("IDFlag"); if(IDFlag==1){Boss b=new Boss();} else { Staff s=new Staff(); } dispose(); } } catch (SQLException e1) { e1.printStackTrace(); } SqlOperation.release(statement, con); } } }); } } |
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论