资源描述
仓库管理系统
一、课程设计的内容
1、研究与学习仓库管理系统的技术、发展和意义;
2、学习使用仓库管理系统,掌握应用开发工具Visual Studio、中间层数据库访问技术ADO以及关系数据库MS SQL Server2000等实现技术的基本原理,安装配置系统开发环境;
3、设计和实现仓库进销存管理系统;
4、撰写课程设计报告。
二、课程设计的要求
1、本系统要能够完成仓库管理的一般工作,例如商品的出入库、余量统计等等。
2、实现数据库的增、删、改、查功能。
3、实现用户的权限管理.
4、掌握处于中间层的数据库访问技术.
三、课程设计应完成的工作
1、开发一个基于B/S架构的仓库管理系统,功能包括:管理员设置、仓管员登陆、仓管员设置、各仓库商品出入库、库存统计等等。
2、通过规划设计本数据库系统,掌握数据库规划设计的基本技术,熟悉数据库的设计的基本方法和步骤,明白数据库设计各阶段的任务,加深对数据库系统概念和特点的理解。
3、独立撰写课程设计报告,对整个系统及其内部的各个功能模块的构想、设计思路、实现方法和过程,做出了详细的说明和介绍。
四、主要设备与软件:
1.计算机及操作系统:PC机,Windows XP
2.数据库管理系统:Visual Studio 2005+SQL sever 2000
五、相关技术介绍
1.应用开发工具Visual Studio
Visual Studio(VS)是一种由微软公司开发的包含协助开发环境的事件驱动编程语言。VS拥有图形用户界面(GUI)和快速应用程序开发(RAD)系统,可以轻易的使用DAO、RDO、ADO连接数据库,或者轻松的创建ActiveX控件。程序员可以轻松的使用VS提供的组件快速建立一个应用程序。它非常适合用来开发拥有友好界面的程序(比如针对终端的数据),但是不适合开发其它程序(比如联合计算程序)。
2.关系数据库SQL Server 2000
SQL Server 是一个关系数据库管理系统,而SQL Server 2000 是Microsoft 公司推出的SQL Server 数据库管理系统,它具有以下特点:
(1)高性能设计,可充分利用WindowsNT的优势。
(2)系统管理先进,支持Windows图形化管理工具,支持本地和远程的系统管理和配置.
(3)强壮的事务处理功能,采用各种方法保证数据的完整性.
(4)支持对称多处理器结构、存储过程、ODBC,并具有自主的SQL语言。 SQLServer以其内置的数据复制功能、强大的管理工具、与Internet的紧密集成和开放的系统结构为广大的用户、开发人员和系统集成商提供了一个出众的数据库平台.
3。ADO。Net数据库访问技术
微软公司的ADO (ActiveX Data Objects) 是一个用于存取数据源的COM组件。它提供了编程语言和统一数据访问方式OLE DB的一个中间层。允许开发人员编写访问数据的代码而不用关心数据库是如何实现的,而只用关心到数据库的连接。访问数据库的时候,关于SQL的知识不是必要的,但是特定数据库支持的SQL命令仍可以通过ADO.Net中的命令对象来执行.
本系统采用目前比较流行的ADO.Net,并将每个数据库表的字段和操作封装到类中,从而成功地将面向对象的程序设计思想应用到数据库应用程序设计中.
六、概述
仓库系统能够有效地管理商品资源,控制商品出入库以及其各类统计,减少人工手工记录的麻烦,极大地帮助了减轻了仓库管理员的工作量,使得仓库管理变得智能化。这个系统利用Visual Studio作为开发工具,MS SQL Server 2000作为数据库管理系统,利用ADO。Net数据库访问技术,建立一个B/S架构的关系数据库系统。通过系统的开发,让读者了解有关仓库管理系统的需求分析、设计和实现的完整过程,并且有利于掌握有关SQL Server 2000数据库的技术,积累开发数据库应用系统的经验。
七、系统需求分析
仓库管理系统的用户是负责仓库商品出入库以及统计的管理员,该系统能够方便管理员对商品进行有效的管理,为仓库物力节省了人力物力上等资源。系统包括了管理员登陆设置、商品信息入库、商品出库、商品退货、商品销售统计和商品库存统计等主要功能。
l 管理员登陆设置:开设删除仓库和仓库管理员
l 商品信息入库:商品信息添加至对应仓库数据库
l 商品出库:出库商品信息添加至对应仓库数据库
l 商品退货:退货商品信息添加至对应仓库数据库
l 商品销售统计:统计数据库内商品销售的信息
l 商品库存统计:统计数据库内商品剩余的信息
(1)仓库管理系统第一层数据流图
仓库管理系统根据登陆用户的不同,将自动跳转到相应面页。
① 系统管理员
系统管理员实现对仓库的开设和相应级别管理员的设置。
② 仓管员
包括总仓管和一般仓库管理员.
总仓管可以实现对所有仓库信息的统计和各仓库间商品的调拨。
一般仓库管理员只能对自己所管理的仓库的商品信息的操作,事实上对其他仓库的信息其无法得知。
登陆
管理员
开设仓库
失败
设置管理员
总仓管
商品调拨查询操作
仓管员
商品出入库查询统计操作
图书借阅管理系统第一层数据流图
第一层数据流图通过反映了整个系统不同数据的流向,揭示系统的组成结构以及各组成部分之间的关系,这种关系主要体现在对数据的操作和处理上。
(2)出入库处理
在商品出入库操作中,首先填写或选择所需出入库的信息,进行检查,如果输入信息正确则进入下一步,如果无效则给操作者相应的提示,页面自动跳转。具体操作的数据流图如下图所示:
仓管员
入库
出库
商品信息
仓库
操作失败
商品信息
查询
出入库过程
写入
仓库记录
显示记录
出入库等操作的数据流图
(3)商品调拨处理
在商品调拨操作中,首先根据所需调拨商品所属仓库进行有效性判断,如果有效则进入下一步,如果是无效则给操作者相应的提示,页面自动跳转。
在商品调拨前后,商品调拨记录表以及调拨仓库的数据表中均插入数据操作记录,以便查询统计。
调拨信息记录
操作的数据流图如下图所示:
删除
商品信息
仓库二
仓库一
仓库二
查询信息
仓库一
入库
出库
商品信息
写入
还书操作的数据流图
(5)在需求分析的最后,形成了以下与数据流图相配对的数据字典如下:
数据项:serId
含义说明:惟一标识一个用户
别名:用户ID
长度:15
取值范围:字符型
数据结构:商品
含义说明:定义了一种商品的信息结构,也即是供操作的信息结构。
组成:商品Id,商品名,商品类型,商品数量,供应商等
数据存储:用户列表
说明:表示各类仓库管理员的信息
数据分类:系统管理员,总仓管,仓管员
组成:用户Id,用户名,用户级别,所管理仓库
数据存储:仓库列表
说明:记录每一个仓库的情况
流入数据流:仓库信息
流出数据流:仓库信息
存取方式:随机存取
处理过程:仓库表
说明:对应每个仓库的数据表
输入:各仓库商品信息
输出:商品出库信息
处理:首先判断商品信息的可用性,然后执行所要求操作
(6)安全性与完整性要求:
安全性要求:
本系统中,首先给数据库添加Window用户,设置一位系统管理员;通过管理员开设仓库和设置仓库管理员,管理员登陆后根据自身身份,跳转至相应页面,实现了访问数据库的权限。
完整性要求:
在数据库中对数据库所需要的表设置完整性约束,为各表设置表的主键,规定各表之间的关系,另外还需要设置一组外键。
其中,各表主键分别如下:
用户信息表UserList——主键userName
仓库信息表StoreList—-主键storeName
调拨信息表ManagerTable--主键pId
(7)触发器建立仓库表
为了实现系统的自动化,和有效节省存储空间以及消除数据表的冗余,未设置的仓库一律不配数据库表,而只有当仓库开设成功后才建立相应的仓库表.此动作在系统中是通过触发器来实现的。
触发器中建立仓库表,一旦该仓库给删除,后台代码同样有将该仓库表删除的操作。
建立的触发器如下:
CREATE TRIGGER creatnew ON dbo.StoreList
AFTER INSERT
AS
declare @storeName char(15)
select @storeName=[storeName] from inserted
exec(’create table '+@storeName+'
( pId int IDENTITY (1, 1) NOT FOR REPLICATION NOT NULL ,
pName varchar(15),
pKind varchar(15),
pCount int,
pMin int,
pUnit varchar(4),
pIn float,
pOut float,
pBack float,
pTime datetime null,
pServe varchar(30),
pPerson varchar(15),
pByer varchar(30),
pState char(8),
pRemark varchar(150)
)’
)
而在后台代码删除数据表的操作是通过以下代码实现的:
SqlConnection conn = new SqlConnection(strConnect);
conn。Open();
string deleteid = StoreGrid。DataKeys[e。RowIndex]。Value。ToString();
string datesql=”select * from ”+deleteid ;
SqlCommand objCmd1 = new SqlCommand(datesql, conn);
SqlDataReader myReader = objCmd1.ExecuteReader();
if (myReader。Read())
{
Response。Write("〈script〉alert('该仓库中还保存有货物,请先通过总仓管将货物调入其他仓库!’)</script>”);
return;
}
myReader.Close();
string dropTable = "drop table ” + deleteid;
SqlCommand objCmd2 = new SqlCommand(dropTable, conn);
objCmd2。ExecuteNonQuery();
string strsql = "delete from StoreList where storeName=’" + deleteid + ”'”;
SqlCommand objCmd3 = new SqlCommand(strsql, conn);
objCmd3。ExecuteNonQuery();
conn。Close();
八、逻辑结构设计
(1)系统结构图
仓库管理系统的系统结构图如下所示:
开设仓库
设置仓管员
仓管员
商品出库
商品入库
系统管理员操作
系统登陆
系统用户管理
库存统计
商品调拨
调拨查询
库存查询
仓库管理系统
(3)安全性和完整性设计
根据需求分析的说明,安全性设计是通过设置Windows用户以及SQL角色、对象等的权限来实现的,具体如下:
①新建数据库登陆用户:
②建立好用户后,给用户设置角色已经分配权限,因为超级管理员Administrator与普通管
理员rekku设计情况相类似,所以下面只引用Administrator作为例子.
③ 设置完用户属性后,还可以设置对象属性,给用户分配访问对象权限(以表BookInfo为例):
九、概念结构设计
E—R图为实体—联系图,提供了表示实体型、属性和联系的方法,用来描述现实世界的概念模型。下面用E—R图来表示本仓库管理系统的概念结构设计。
①用户和仓库的E-R图
用户ID
仓库名
仓库
仓库面积
密码
1
1
管理
用户
用户名
户名
仓库地址
②仓库和仓库列表的分E—R图
价格
商品名
仓库名
商品ID
n
商品供应商
仓库面积
仓库列表
1
对应
仓库
仓库地址
商品类型
仓管员
数量
十、数据库物理设计
(1)数据库存放位置:
在某些情况下,数据库管理员 (dba) 经常希望某个数据库会位于服务器数据文件夹之外。这些情况通常是由于业务需要,如提高性能或扩展存储。由于本数据库是在一台PC机建立的,基于扩展存储的考虑,本数据库的数据库文件与日志文件存放在不同分区当中。如下所示:
数据库文件:
日志文件:
十一、数据库实施
(1)本图书借阅管理系统中,创建的数据库有如下数据库对象:
表StoreList
CREATE TABLE [dbo]。[StoreList] (
[storeName] [char] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[storeArea] [float] NULL ,
[storeAddress] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[storeManager] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
表ManagerTable
CREATE TABLE [dbo].[ManagerTable] (
[pId] [int] IDENTITY (1, 1) NOT FOR REPLICATION NOT NULL ,
[pName] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[pKind] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[pCount] [int] NULL ,
[pTime] [datetime] NULL ,
[pPerson] [varchar] (30) COLLATE Chinese_PRC_CI_AS NULL ,
[pFrom] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[pTo] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[pRemark] [varchar] (150) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
表UserList
CREATE TABLE [dbo]。[UserList] (
[userId] [varchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[userPwd] [char] (16) COLLATE Chinese_PRC_CI_AS NULL ,
[userName] [char] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[userFlag] [int] NULL ,
[userLevel] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
仓库表示例—触发器建立
CREATE TABLE [dbo]。[仓库三] (
[pId] [int] IDENTITY (1, 1) NOT FOR REPLICATION NOT NULL ,
[pName] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[pKind] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[pCount] [int] NULL ,
[pMin] [int] NULL ,
[pUnit] [varchar] (4) COLLATE Chinese_PRC_CI_AS NULL ,
[pIn] [float] NULL ,
[pOut] [float] NULL ,
[pBack] [float] NULL ,
[pTime] [datetime] NULL ,
[pServe] [varchar] (30) COLLATE Chinese_PRC_CI_AS NULL ,
[pPerson] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[pByer] [varchar] (30) COLLATE Chinese_PRC_CI_AS NULL ,
[pState] [char] (8) COLLATE Chinese_PRC_CI_AS NULL ,
[pRemark] [varchar] (150) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
(2)数据库备份和恢复方案:(待完)
由于仓库管理过程中,商品流动量大,添加新商品的周期也不长,这些原因使得商品数量庞大,对流快速,这就要求数据库备份时,采用完全恢复方案。完全恢复对所有的事务都进行了日志记录,当发生故障时,这种方案能够将数据库中每个提交的事务都还原到故障发生时的状态。
在这个完全恢复备份方案,具体设计为每个星期进行两次完全的数据库备份,除去这两天以外,在一个星期的其他几天的每个晚上都要进行差异备份。此外,每个白天进行三次事务日志备份。
备份方案示意图:
星期五 差异备份+事务日志备份
星期日 完全备份
星期一 差异备份+事务日志备份
星期三 完全备份
星期四 差异备份+事务日志备份
星期二 差异备份+事务日志备份
星期六 差异备份+事务日志备份
(3)系统首页
① 用户登陆界面,在用户输入账户和密码的时候,将判断正确性,代码如下:
#region
string pwds = userID。Text.ToString();
//MD5加密存储
byte[] pass = Encoding。UTF8.GetBytes(pwds);
MD5 md5 = newMD5CryptoServiceProvider();
string strPassword = Encoding。UTF8。GetString(md5。ComputeHash(pass));
SqlConnection conn = newSqlConnection(strConnect);
conn。Open();
string strsql = ”select * from UserList where userId=’" + userID。Text.Trim() + ”’and userPwd=’” + strPassword + "’”;
string stosql = "select storeName from storeList where storeManager=’” + userID。Text.Trim() +"'";
SqlCommand objCmd = newSqlCommand(strsql, conn);
SqlCommand objCmd2 = newSqlCommand(stosql, conn);
//objCmd。Connection。Close();
SqlDataReader dr2 = objCmd2.ExecuteReader();
string logStoreName = ””;
if (dr2.Read())
{
logStoreName = dr2[0]。ToString();
}
objCmd2。Connection.Close();
objCmd。Connection。Open();
SqlDataReader dr = objCmd.ExecuteReader();
#endregion
if (dr。Read())
{//根据用户级别不同,自动导航到相应页面
string logUserId=dr[0].ToString();
Session[”userFlag”] = dr[”userFlag”];
if (Session["userFlag"].ToString() == "0")
{
Response.Redirect("AdminsetShow。aspx?user=” + logUserId + ”&store=” + logStoreName);
}
if (Session[”userFlag"].ToString() == ”1")
{
Response。Redirect(”MainManager。aspx?user=” + logUserId);
}
if (Session[”userFlag”]。ToString() == "2")
{
Response。Redirect("SubManager。aspx?user=” + logUserId + ”&store=" + logStoreName);
}
}
else
{
//Response。Redirect("Adminset。aspx”);
Response。Write(”<script>alert(’用户名或密码错误!')〈/script〉”);
}
conn。Close();
}
新增仓库:
设置管理员:
退出系统将返回登陆界面:
②管理员进入后,可以进行仓库开设、仓管员设置等;当前页面显示已经添加有若干信息:
③仓管员进入后界面如下:
点击左边导航栏,可以显示不同的信息操作界面:如下:
//页面传值
logUserId = Request。QueryString[”user"];
logStoreName = Request。QueryString["store”];
#region相应页面加载
if (Session["flag"] =="InShow”)
{
productInfoBind();
}
if (Session[”flag”] == "OutShow")
{
productOutBind();
}
if (Session[”flag”] == ”BackShow”)
{
productBackplBind();
}
if (Session[”flag”] == ”SearchShow”)
{
searchpKind。Items。Clear();
searchpByer.Items。Clear();
searchpSever。Items。Clear();
SellplBind();
}
if (Session["flag”] == ”RemainShow”)
{
RemainplBind();
}
#endregion
}
privatevoid productOutBind() //商品出库页面
{
productInfo.Visible = false;
productOut。Visible = true;
productBackpl.Visible = false;
Sellpl。Visible = false;
Remainpl。Visible = false;
SqlConnection conn = newSqlConnection(strConnect);
conn.Open();
SqlCommand sc = newSqlCommand(”select distinct pName,pKind,pUnit,pServe from " + logStoreName, conn);
SqlDataReader myReader = sc。ExecuteReader();
while (myReader。Read())
{
pName1。Items。Add(myReader[0].ToString());
pKind1.Items。Add(myReader[1].ToString());
pUnit1。Items.Add(myReader[2]。ToString());
pSever1。Items。Add(myReader[3].ToString());
}
conn。Close();
}
privatevoid productBackplBind() //商品退货页面
{
productInfo。Visible = false;
productOut。Visible = false;
productBackpl。Visible = true;
Sellpl。Visible = false;
Remainpl。Visible = false;
//信息加载
SqlConnection conn = newSqlConnection(strConnect);
conn。Open();
SqlCommand sc = newSqlCommand(”select distinct pName,pKind,pUnit,pByer,pServe from " + logStoreName, conn);
SqlDataReader myReader = sc.ExecuteReader();
while (myReader。Read())
{
pName2.Items。Add(myReader[0]。ToString());
pKind2。Items.Add(myReader[1]。ToString());
pUnit2.Items。Add(myReader[2].ToString());
pByer2.Items.Add(myReader[3].ToString());
pSever2。Items.Add(myReader[4]。ToString());
}
conn。Close();
}
privatevoid searchBind() //查找数据
{
SqlConnection conn = newSqlConnection(strConnect);
string ziduan = ”pName as 商品名,pKind as 商品类型,pCount as 库存余量,pIn as 进货价,pOut as 出库价,pByer as 买家,pServe as 供应商,pTime as 时间";
SqlCommand acd = newSqlCommand(”select " + ziduan + ” from ” + logStoreName + ” where pState='出库’ ” + sqlWhere, conn);
acd。Connection。Open();
SqlDataReader sda = acd。ExecuteReader();
this。searchGrid。DataSource = sda;
this。searchGrid.DataBind();
acd.Connection。Close();
searchCount。Text = searchGrid.Rows.Count。ToString();
}
privatevoid remainData() //商品库存数据
{
SqlConnection conn = newSqlConnection(strConnect);
string ziduan = ”pName as 商品名,pKind as 商品类型,pCount as 库存余量,pServe as 供应商”;
SqlCommand acd = newSqlCommand("select ” + ziduan + ” from ”+logStoreName, conn);
acd.Connection。Open();
SqlDataReader sda = acd。ExecuteReader();
this.remainGrid。DataSource = sda;
this。remainGrid。DataBind();
acd。Connection。Close();
remainCount。Text = remainGrid。Rows.Count.ToString();
}
protectedvoid btnPutIn_Click(object sender, EventArgs e) //新商品入库
{
SqlConnection conn = newSqlConnection(strConnect);
SqlCommand sd = newSqlCommand(”insert into " + logStoreName + ” (pName,pKind,pCount,pMin,pUnit,pIn,pServe,pRemark,pState,pPerson,pTime) "+
”Values (@pName,@pKind,@pCount,@pMin,@pUnit,@pIn,@pServe,@pRemark,@pState,@pPerson,@pTime)”, conn);
sd。Parameters。Add(newSqlParameter(”@pName", pName。Text));
sd。Parameters。Add(newSqlParameter("@pKind”, pKind.Text.Trim()));
sd。Parameters。Add(newSqlParameter(”@pCount", int。Parse(pCount。Text。Trim()))); //入库数量
sd。Parameters。Add(newSqlParameter(”@pMin", int.Parse(pMin。Text。Trim())));
sd。Parameters。Add(newSqlParameter("@pUnit", pUnit。Text));
sd。Parameters.Add(newSqlParameter(”@pIn”, float。Parse(pIn.Text。Trim())));
sd。Parameters.Add(newSqlParameter(”@pServe”, pSever。Text));
sd。Parameters。Add(newSqlParameter(”@pRemark”, pRemark。Text));
sd。Parameters.Add(newSqlParameter(”@pState”, ”入库”));
sd。Parameters。Add(newSqlParameter(”@pPerson", logUserId));
sd。Parameters。Add(newSqlParameter("@pTime”, DateTime。Now));
sd。Connection。Open();
try
{
int a = Convert.ToInt32(sd。ExecuteNonQuery());
if (a > 0)
{
Response.Write(”〈script>alert(’操作成功!’)</script〉”);
Response。Redirect(”SubManager。aspx?user=” + logUserId + ”&store=" + logStoreName);
}
}
catch (SqlException ex)
{
Response.Write(ex。ToString());
//Response。Write("〈script>alert('添加失败!’)〈/script>”);
sd。Connection。Close();
return;
}
finally
{
if (sd。Connection。State == ConnectionState。Open)
展开阅读全文