进销存系统中的先进先出,指得是利用队列原理——先采购进来的商品先卖出。
这里我用SQL Server的存储过程来实现这个功能。
关于这个存储过程的调用和演示说明,请查看 这里
这个存储过程在SQL Server 2000上编译通过并运行,
使用Oracle? 前往。
字段名
|
字段类型
|
字段长度
|
是否可空
|
备注
|
pId
|
nvarchar
|
20
|
No
|
这是商品的编号
|
stockNo
|
int
|
4
|
no
|
当前要放的仓库编号,初始值为1
|
marketNo
|
Int
|
4
|
No
|
当前要出售商品的仓库编号,由于初始状态所有仓库都没有货,初始值为0
|
num1
|
numeric
|
6
|
No
|
第1仓库的数量,初始值为0
|
cost1
|
numeric
|
5,2
|
no
|
第1仓库的成本价,初始为0
|
Num2
|
numeric
|
6
|
No
|
第2仓库的数量,初始值为0
|
Cost2
|
numeric
|
5,2
|
no
|
第2仓库的成本价,初始为0
|
Num3
|
numeric
|
6
|
No
|
第3仓库的数量,初始值为0
|
Cost3
|
numeric
|
5,2
|
no
|
第3仓库的成本价,初始为0
|
Num4
|
numeric
|
6
|
No
|
第4仓库的数量,初始值为0
|
Cost4
|
numeric
|
5,2
|
no
|
第4仓库的成本价,初始为0
|
Num5
|
numeric
|
6
|
No
|
第5仓库的数量,初始值为0
|
Cost5
|
numeric
|
5,2
|
no
|
第5仓库的成本价,初始为0
|
Num6
|
numeric
|
6
|
No
|
第6仓库的数量,初始值为0
|
Cost6
|
numeric
|
5,2
|
no
|
第6仓库的成本价,初始为0
|
数据库创建脚本 下载
- if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ProductSM]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
- drop table [dbo].[ProductSM]
- GO
- CREATE TABLE [dbo].[ProductSM] (
- [pId] [nvarchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
- [stockNo] [int] NOT NULL ,
- [marketNo] [int] NOT NULL ,
- [num1] [numeric](6, 0) NOT NULL ,
- [cost1] [numeric](5, 2) NOT NULL ,
- [num2] [numeric](6, 0) NOT NULL ,
- [cost2] [numeric](5, 2) NOT NULL ,
- [num3] [numeric](6, 0) NOT NULL ,
- [cost3] [numeric](5, 2) NOT NULL ,
- [num4] [numeric](6, 0) NOT NULL ,
- [cost4] [numeric](5, 2) NOT NULL ,
- [num5] [numeric](6, 0) NOT NULL ,
- [cost5] [numeric](5, 2) NOT NULL ,
- [num6] [numeric](6, 0) NOT NULL ,
- [cost6] [numeric](5, 2) NOT NULL
- ) ON [PRIMARY]
- GO
存储过程设计 下载
代码中有详细的解释,都是作者亲自编写,欢迎提出建议。
- ------------------------------------------------
- ----------Author nileader-----------------------
- ----------Date 2010/04/24-----------------------
- ------------------------------------------------
- ALTER PROC pro_ProductSM
- -- ------------参数声明
- @SorM char(2), --表征当前业务是进货还是出售 S--进货 M--出售
- @pId nvarchar(20), --表征操作的商品id
- @marketPrice nvarchar(10), --如果当前的业务是M,那么这个参数有效, 表示这次出售的价格
- @marketNum nvarchar(10), --如果当前的业务是M,那么这个参数有效,表示这次出售的数量
- @stockPrice nvarchar(10), --如果当前的业务是S,那么这个参数有效,表示这次进货的成本单价
- @stockNum nvarchar(10) --如果当前的业务是S,那么这个参数有效,表示这次进货的数量
- AS
- BEGIN
- DECLARE
- @stockNo int, --当前可以进货的仓库编号 仓库最大6个
- @marketNo int, --当前可以出售的仓库编号 仓库最大6个
- @updateSQL nvarchar(200) --一个待构造的sql update 语句
- --选择操作业务 进货还是出售 S--进货 M--出售
- --以下是进货操作
- IF @SorM = 'S'
- BEGIN
- --让用户知道自己在干什么
- PRINT '提示信息:你即将以成本单价为'+@stockPrice+',进货一种编号为'+@pId
- +'的东西'+@stockNum+'件'
- --取出当前可以进货的编号
- SELECT @stockNo=stockNo, @marketNo=marketNo
- FROM ProductSM WHERE pId=@pId
- --判断是否可以继续进货
- IF @stockNo >=7 --不能继续进货了
- BEGIN
- PRINT '所有仓库已经有货,不能再继续进货了'
- END
- ELSE --还能继续进货 1 <= @stockNo <=6
- BEGIN
- PRINT '开始更新数据库中的'+@pId
- -- 构造出要更新的num和cost字段, 拼装成sql语句
- DECLARE
- @_numx nvarchar(10) , --要更新的num号
- @_costx nvarchar(10) --要更新的cost号
- SET @_numx = 'num' + CONVERT(nvarchar(10),@stockNo)
- SET @_costx = 'cost' + CONVERT(nvarchar(10),@stockNo)
- SET @updateSQL ='UPDATE ProductSM SET '+@_numx+'='+@stockNum+', '
- +@_costx+'='+@stockPrice+', stockNo=stockNo+1 WHERE pId='+@pId
- EXEC(@updateSQL);
- -- 如果之前所有的仓库都是空的,
- -- 那么marketNo=0,即没有指向任何可以出售的仓库,
- -- 那么现在要让他指向第一个仓库
- IF @marketNo = 0
- BEGIN
- UPDATE ProductSM SET marketNo = 1 WHERE pId = @pId
- END
- --让用户知道自己在干了什么
- PRINT '提示信息:你成功地以成本单价为'+@stockPrice
- +',进货了一种编号为'+@pId+'的东西'+@stockNum+'件'
- END
- END
- -- =======以上是进货操作
- -- 以下是出售操作
- IF @SorM = 'M'
- BEGIN
- --让用户知道自己在干什么
- PRINT '提示信息:你即将以单价为 '+@marketPrice+' 出售一种编号为 '
- +@pId+' 的东西 '+@marketNum+'件'
- DECLARE
- -- 各个仓库现在的数量
- @num1 numeric(6), --第1个仓库当前的数量
- @num2 numeric(6), --第2个仓库当前的数量
- @num3 numeric(6), --第3个仓库当前的数量
- @num4 numeric(6), --第4个仓库当前的数量
- @num5 numeric(6), --第5个仓库当前的数量
- @num6 numeric(6), --第6个仓库当前的数量
- @totalNum numeric(7), --现在所有仓库中的数量和
- @cost1 numeric(5,2), --第1个仓库当前的成本
- @cost2 numeric(5,2), --第2个仓库当前的成本
- @cost3 numeric(5,2), --第3个仓库当前的成本
- @cost4 numeric(5,2), --第4个仓库当前的成本
- @cost5 numeric(5,2), --第5个仓库当前的成本
- @cost6 numeric(5,2) --第6个仓库当前的成本
- -- 如果marketNo 大于stockNo 终止
- --取出当前可以出售的编号和进货编号
- SELECT @marketNo=marketNo, @stockNo = stockNo
- FROM ProductSM WHERE pId=@pId
- IF @marketNo > @stockNo
- BEGIN
- PRINT '出售编号大于进货编号,怎么可能?我得去仓库看看了。'
- END
- ELSE
- BEGIN
- PRINT '仓库概况:当前进货编号为'+CAST(@stockNo AS nvarchar)
- +' 出售编号为'+CAST(@marketNo AS nvarchar)
- -- 统计出现在所有的库存量,用来检测这次出售交易是否超过了所有仓库的供给量
- SELECT @num1=num1,@cost1=cost1, @num2=num2,@cost2=cost2,
- @num3=num3,@cost3=cost3, @num4=num4,@cost4=cost4,
- @num5=num5,@cost5=cost5, @num6=num6,@cost6=cost6
- FROM ProductSM WHERE pId=@pId
- SET @totalNum = @num1 + @num2 + @num3 + @num4 + @num5+ @num6
- --如果现在的所有数量都不能满足你的要求,那就只好说再见了
- IF @totalNum < @marketNum
- BEGIN
- print '不好意思,你的需求过大,交易失败'
- END
- ELSE IF @totalNum >= @marketNum
- BEGIN
- --取出当前可以出售的编号
- SELECT @marketNo=marketNo FROM ProductSM WHERE pId=@pId
- -- 从当前可以出售的开始,即@marketNo开始一个一个卖,知道满足marketNum需求
- DECLARE
- --是否完成交易,1表示完成,0表示没有完成,
- --这个标识用来表示在一个一个仓库卖的过程中,是否可以满足需求,终止此次交易
- @flag int
- SET @flag = 0
- DECLARE
- @thisWant numeric(6), -- 现在还要的需求
- @thisNum numeric(6), -- 现在所在的仓库有多少货
- @thisCost numeric(5,2) -- 现在所在的仓库的成本
- SET @thisWant = @marketNum
- WHILE @flag = 0
- BEGIN
- --取出当前可以进货的编号
- SELECT @marketNo=marketNo FROM ProductSM WHERE pId=@pId
- IF @marketNo = 1
- BEGIN
- SET @thisNum = @num1
- SET @thisCost = @cost1
- SET @_numx ='num1'
- SET @_costx = 'cost1'
- END
- ELSE IF @marketNo = 2
- BEGIN
- SET @thisNum = @num2
- SET @thisCost = @cost2
- SET @_numx ='num2'
- SET @_costx = 'cost2'
- END
- ELSE IF @marketNo = 3
- BEGIN
- SET @thisNum = @num3
- SET @thisCost = @cost3
- SET @_numx ='num3'
- SET @_costx = 'cost3'
- END
- ELSE IF @marketNo = 4
- BEGIN
- SET @thisNum = @num4
- SET @thisCost = @cost4
- SET @_numx ='num4'
- SET @_costx = 'cost4'
- END
- ELSE IF @marketNo = 5
- BEGIN
- SET @thisNum = @num5
- SET @thisCost = @cost5
- SET @_numx ='num5'
- SET @_costx = 'cost5'
- END
- ELSE IF @marketNo = 6
- BEGIN
- SET @thisNum = @num6
- SET @thisCost = @cost6
- SET @_numx ='num6'
- SET @_costx = 'cost6'
- END
- DECLARE @money numeric(5,2) -- 盈利
- --判断这个仓库是否可以满足这个交易的需求
- --如果这个仓库比需求大,那么出售marketNum件商品就ok了
- IF @thisWant < @thisNum
- BEGIN
- PRINT '提示信息:本次交易以 '+@marketPrice+' 出售一种成本为'
- +CAST(@thisCost AS nvarchar)+'号为'+@pId+' 的东西 '
- +CONVERT(nvarchar(6),@thisWant)+'件'
- -- 算一下赚了多少钱
- SET @money = (@marketPrice - @thisCost) * @thisWant
- PRINT '算一下赚了多少钱:' +CAST(@money AS nvarchar)
- --更新数据库中的仓库信息
- SET @updateSQL ='UPDATE ProductSM SET '+@_numx+'='
- +CAST(@_numx AS nvarchar)+'-'
- +CAST(@thisWant AS nvarchar)+' WHERE pId='+@pId
- EXEC(@updateSQL);
- --做一些收尾工作
- SET @thisWant = 0 --都满足需求了,肯定置为0了
- SET @flag = 1 --表示已经完成了
- END
- --如果这个仓库和需求一样,那么出售这个仓库的所有,并把marketNo指向下一个仓库
- ELSE IF @thisWant = @thisNum
- BEGIN
- PRINT '提示信息:本次交易以 '+@marketPrice+' 出售一种成本为'
- +CAST(@thisCost AS nvarchar)
- +'号为'+@pId+' 的东西 '+CONVERT(nvarchar(6),@thisWant)+'件'
- -- 算一下赚了多少钱
- SET @money = (@marketPrice - @thisCost) * @thisWant
- PRINT '算一下赚了多少钱:' +CAST(@money AS nvarchar)
- --更新数据库中的仓库信息
- SET @updateSQL ='UPDATE ProductSM SET marketNo = marketNo + 1,'
- +@_numx+'=0,'+@_costx+'=0 WHERE pId='+@pId
- EXEC(@updateSQL);
- --做一些收尾工作
- SET @thisWant = 0 --都满足需求了,肯定置为0了
- SET @flag = 1 --表示已经完成了
- END
- --如果这个仓库比需求小,那么出售这个仓库的所有,并把marketNo指向下一个仓库,继续下一个循环
- ELSE IF @thisWant > @thisNum
- BEGIN
- PRINT '提示信息:本次交易以 '+@marketPrice+' 出售一种成本为'
- +CAST(@thisCost AS nvarchar)
- +'号为'+@pId+' 的东西 '+CONVERT(nvarchar(6),@thisNum)+'件'
- -- 算一下赚了多少钱
- SET @money = (@marketPrice - @thisCost) * @thisNum
- PRINT '算一下赚了多少钱:' +CAST(@money AS nvarchar)
- --更新数据库中的仓库信息
- SET @updateSQL ='UPDATE ProductSM SET marketNo = marketNo + 1,'
- +@_numx+ WHERE pId=''=0,'+@_costx+'=0+@pId
- EXEC(@updateSQL);
- --做一些收尾工作
- SET @thisWant = @thisWant - @thisNum --都满足需求了,肯定置为0了
- END
- END
- END
- END
- END
- -- ========以上是出售操作
- END