2024年5月7日发(作者:)

超市管理系统不一定要那么多的表

系统数据库表结构

数据库表索引

表名

Userifo

Supplier

GoodsType

Goods

Buy

Sale

Spoilage

自定义数据类型(custem)

字段名 数据类型 长度 主/外键

gcxCaptio

n

gxcID

gxcMoney

ney

gxcRemar

k

gxcTrueN

ame

商品信息表(Goods)

字段名 数据类型 长度 主/外键

GoodsID

GoodsNa

me on

gxcID

gxcCapti

4

100

P

Not null

Not null

字段值约

Varchar 10 Not null 真实姓名

Varchar 1000 Null 备注说明

Int

Smallmo

4

4

P

Not null

Not null

实体号

进货销售金额

Varchar 100 Not null

字段值约

中文名

系统用户表

供货商信息表

商品类型表

商品信息表

进货表

销售表

损坏商品表

对应中文名

实体名称

对应中文名

商品号码

商品名称

Amount

UnitNam

e

TypeID

SupplierI

D

Introduce

rk

Remark

rk

on

Decimal1

gxcCapti

9

100

Not null

Not null

库存数量

单位名称

gxcID

gxcID

4

4

Not null

Not null

商品类型号

商品供货商号

gxcRema1000 Null 商品介绍

gxcRema1000 Null 备注

用户表(UserInfo)

字段名 字段类型

UserID

UserName

on

Password

on

TrueName gxcTrue

Name

LastLoginTi

me

UserType Bit 1

销售表(Sale)

字段名 字段类型

SaleID

GoodsID

Amount

UnitPrice

gxcID

gxcID

Decimal

gxcMone

4

1

9

4

P

F

Not null

Not null

Not null

Not null

主/外字段值约束

Not Null 用户类型

Datetime 8 Not null 最近登录时间

10 Null 真实姓名

gxcCapti100 Not null 用户密码

gcxID

gxcCapti

4

100

P

Not null

Not null

主/外字段值约束

对应中文名

用户号

用户名称

对应中文名

销售号

商品号

销售数量

单价

y

registrarID

regDate

Remark

ark

gxcID

Datetime

gxcRem

0

进货信息表(Buy)

字段名 字段类型

BuyID

GoodsID

Amount

UnitPrice

y

Deliverer gxcTrue

Name

Transactor gxcTrue

Name

RegistrarID

Regdate

Remark

ark

gxcID

Datetime

gxcRem

0

损坏商品表(Spoilage)

字段名 字段类型

SpoilageID

BuyID

Amout

Reportor

ame

gxcID

gxcID

Decimal

gxcTrueN

4

4

9

10

P

F

Not null

Not null

Not null

Not null

主/外字段值约束

4

8

100

F

Not null

Not null

Null

录入人员号

登记时间

备注

10 Null 办理员

10 Null 送货员

gxcID

gxcID

Decimal

gxcMone

4

4

9

4

P

Not null

Not null

Not null

Not null

主/外字段值约束

4

8

100

1

Not null

Null

Null

录入人员号

登记时间

备注

对应中文名

进货编号

商品编号

数量

进货单价

对应中文名

损坏事件号

商品编号

数量

报损人

Reason

k

RegistrarID

Regdate

gxcRemar

0

gxcID

datetime

100 null 损坏原因

4

8

Not Null

Datetime

录入人员号

登记时间

供货商表(Supplier)

字段名 字段类型

SupplierID

SupplierNam

e

Contact

ark

Introduce

ark

Remakr

ark

gxcRem

0

关系图约束设计

数据库关系图如下:

物理结构设计

系统的存储物理结构由数据库来生成。以下为几个例子

查看存在ID字段不为某个值但某个字符型字段等于某个值

/*查看某个数据表中*/

CREATE PROC ameWithoutID

(

@strTableName varchar(255), --表名

@strIDName varchar(255), --ID字段名

@intIDValue int, --ID字段值

gxcRem

0

100 Null 备注

on

gxcRem

0

100 Null 简要介绍

100 Null 联系方式

gxcID

gxcCapti

4

100

P

Not null

Not null

主/外字段值约束

对应中文名

供货商编号

供货商名称

@strFieldName varchar(255), --字符型字段名

@strFieldValue varchar(50), --字符型字段值

@bitResult bit OUTPUT --输出值,0为不存在,1为存在

)

AS

SET NOCOUNT ON

DECLARE @strSQL varchar(3000) --主语句

DECLARE @nCount int --返回记录行数

/*创建存储符合条件的记录数的临时表*/

IF OBJECT_ID('dbo.#tmpTable') IS NULL

CREATE TABLE #tmpTable(tmpField int) --创建临时表

ELSE

TRUNCATE TABLE #tmpTable --清空临时表

/*在数据库表中检索符合条件的记录数并存储在临时表中*/

SELECT @strSQL = 'SELECT COUNT([' + @strFieldName + ']) FROM [' + @strTableName + ']

WHERE [' + @strFieldName + '] = ''' + @strFieldValue + '''' + ' AND ' + @strIDName + ' <> ' +

CONVERT(varchar(50),@intIDValue)

SELECT @strSQl = 'INSERT #tmpTable ' + @strSQL

EXEC(@strSQL)

/*在临时表中返回存储的记录数*/

SELECT TOP 1 @nCount = tmpField FROM #tmpTable ORDER BY tmpField

/*删除临时表*/

DROP TABLE #tmpTable

/*输出参数*/

IF @nCount > 0

SELECT @bitResult = 1

ELSE

SELECT @bitResult = 0

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_NULLS ON

GO

添加一条商品信息

/*添加一条商品信息,输出商品编号和执行结果*/

CREATE PROC ddNew

(

@GoodsName varchar(100), --商品名称

@Amount decimal(18, 2), --库存数量

@TypeID int, --类型编号

@UnitName varchar(100), --单位

@SupplierID int, --供货商编号

@Introduce varchar(1000), --商品介绍

@Remark varchar(1000), --备注

@ID int OUTPUT, --商品编号

@ReturnValue int OUTPUT --执行结果(VB组件的自定义枚举值)

)

AS

DECLARE @ErrNo int --保存错误号

BEGIN TRANSACTION --开始事务

/*手动维护数据唯一性的代码。*/

DECLARE @ExistName bit

EXEC ExistByName 'Goods', 'GoodsName', @GoodsName, @ExistName OUTPUT

IF @ExistName = 1 --当前商品名称已存在

BEGIN

ROLLBACK TRANSACTION --回滚事务

SELECT @ReturnValue = 3 --返回VB组件的自定义枚举值

RETURN --结束存储过程

END

/*添加记录*/

INSERT INTO Goods Values(@GoodsName, @Amount, @UnitName, @TypeID,

@SupplierID, @Introduce, @Remark)

--记录当前的错误号

SELECT @ErrNo = @@ERROR

/*输出参数*/

IF @ErrNo = 0 --没有发生错误

BEGIN

SELECT @ID = (SELECT MAX(GoodsID) FROM Goods)

SELECT @ReturnValue = 0

END

ELSE IF @ErrNo = 2627 --违反唯一约束

BEGIN

ROLLBACK TRANSACTION --遇到错误则回滚事务

SELECT @ReturnValue = 3

RETURN

END

ELSE --其他未知错误

BEGIN

ROLLBACK TRANSACTION --遇到错误则回滚事务

SELECT @ReturnValue = 1

RETURN

END

COMMIT TRANSACTION --提交事务

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_NULLS ON

GO

删除一条商品信息

/*删除一条商品信息,输出执行结果*/

CREATE PROC elete

(

@GoodsID int, --商品编号

@ReturnValue int OUTPUT --执行结果(VB组件的自定义枚举值)

)

AS

DECLARE @ErrNo int --保存错误号

BEGIN TRANSACTION --开始事务

/*验证是否存在当前商品编号,若否则不能删除*/

DECLARE @ExistID bit

EXEC ExistByID 'Goods', 'GoodsID', @GoodsID, @ExistID OUTPUT

IF @ExistID = 0 --当前商品编号不存在

BEGIN

ROLLBACK TRANSACTION --回滚事务

SELECT @ReturnValue = 2 --返回VB组件的自定义枚举值

RETURN --结束存储过程

END

/*手动维护数据完整性的代码*/

EXEC ExistByID 'Buy', 'BuyID', @GoodsID, @ExistID OUTPUT

IF @ExistID = 1

BEGIN

ROLLBACK TRANSACTION

SELECT @ReturnValue = 3

RETURN

END

/*验证销售信息是否包含当前商品,若是则不能删除*/

EXEC ExistByID 'Sale', 'SaleID', @GoodsID, @ExistID OUTPUT

IF @ExistID = 1

BEGIN

ROLLBACK TRANSACTION

SELECT @ReturnValue = 3

RETURN

END

/*删除记录*/

DELETE FROM Goods WHERE GoodsID = @GoodsID

--记录当前的错误号

SELECT @ErrNo = @@ERROR

/*输出参数*/

IF @ErrNo = 0 --没有发生错误

SELECT @ReturnValue = 0

ELSE IF @ErrNo = 547 --发生外键冲突

BEGIN

ROLLBACK TRANSACTION --遇到错误则回滚事务

SELECT @ReturnValue = 3

RETURN

END

ELSE --其他未知错误

BEGIN

ROLLBACK TRANSACTION --遇到错误则回滚事务

SELECT @ReturnValue = 1

RETURN

END

COMMIT TRANSACTION --提交事务

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_NULLS ON

GO

返回所有供货商

CREATE VIEW _Supplier

AS

/*返回所有供货商*/

SELECT SupplierID, SupplierName, Contact, Introduce, Remark FROM Supplier

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

CREATE VIEW _Buy

AS

SELECT , D, ame,

ice, , me,

ice * AS TotalPrice,

rer, ctor, rarID,

e, , erID,

FROM Buy AS B LEFT OUTER JOIN Goods AS G

ON D = D

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_NULLS ON

GO

运行测试

运行模块的组合

具体软件的运行模块组合为程序多窗口的运行环境,各个模块在软件运行过程中能较好的交换信

息,并能够独立的处理各自的数据。

测试及问题提出

软件运行时有较友好的界面,基本能够实现用户的数据处理要求。

问题1:无法进入数据库

问题2:字段名称与SQL关键字冲突

添加字符型数据的时候,如果该数据饮食了单引号,则会造成字符的意外截断而产生错误。

问题3:个别触发器无作用

在Buy表上的delete触发器中,不能完成删除商品信息的时候同步更新商品库存的功能。

问题解决

系统的运行时间基本可以达到用户所提出的要求。问题解决如下

解决问题1:

'设置服务器名称,数据库名称,登录名(此时假设密码为空)

Public Function ConnectToDatabase() As Boolean

On Error GoTo ErrHandler

Set g_Conn = New Connection

Dim ServerName As String, DBName As String, UserName As String, strPassword As String

'连接Sql Server的连接字符串设置

ServerName = "(local)"

DBName = "BuySaleStorage"

UserName = "sa"

strPassword = ""

'连接到SQL Server数据库

根据DB文件夹中的内容,创建数据库,推荐用MDF文件附加数据库;

DBMDFBuySaleStorage_

DBMDFBuySaleStorage_

连接参数:

数据库名:BuySaleStorage

登录名: sa

密码: 你自己定

解决问题2:

当添加字符型数据的时候,如果该数据饮食了单引号,则会造成字符的意外截断而产生错误。解决

方法是把字符数据中的单引号替换为两个单引号,使用了RealString函数来过滤单引号。按照意义对字段

命名,很可能使字段名称与SQL的关键字冲突而产生错误,比如名称为User的字段。解决方法是给字段

名称加上中括号“[]”,使字段名称为“[User]”。

解决问题3:

在SQL Server事务中的操作是作为一个整体来执行的。如果手工约束业务规则和强制数据完整性,

心谤腹非把相应的代码与核心操作代码放在一个事务中,这样的才能保持数据的完整性。对触发器而言,

由于它和激活触发器的语句一起被作为单一的事务来对待,所以即使没有显式地Begin Transaction语句,

在触发器的定义中也可以RollBack Transaction语句。