使用存储过程实现进销存系统中的先进先出算法(1)——数据库与存储过程设计...

         进销存系统中的先进先出,指得是利用队列原理——先采购进来的商品先卖出。

         这里我用SQL Server的存储过程来实现这个功能。

         关于这个存储过程的调用和演示说明,请查看 这里

            这个存储过程在SQL Server 2000上编译通过并运行,

     使用Oracle? 前往

  • 数据库设计

 

表名: ProductSM

字段名
字段类型
字段长度
是否可空
备注
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

 数据库创建脚本   下载

 
 
  1. if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ProductSM]'and OBJECTPROPERTY(id, N'IsUserTable') = 1)  
  2. drop table [dbo].[ProductSM]  
  3. GO  
  4.  
  5. CREATE TABLE [dbo].[ProductSM] (  
  6.     [pId] [nvarchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,  
  7.     [stockNo] [intNOT NULL ,  
  8.     [marketNo] [intNOT NULL ,  
  9.     [num1] [numeric](6, 0) NOT NULL ,  
  10.     [cost1] [numeric](5, 2) NOT NULL ,  
  11.     [num2] [numeric](6, 0) NOT NULL ,  
  12.     [cost2] [numeric](5, 2) NOT NULL ,  
  13.     [num3] [numeric](6, 0) NOT NULL ,  
  14.     [cost3] [numeric](5, 2) NOT NULL ,  
  15.     [num4] [numeric](6, 0) NOT NULL ,  
  16.     [cost4] [numeric](5, 2) NOT NULL ,  
  17.     [num5] [numeric](6, 0) NOT NULL ,  
  18.     [cost5] [numeric](5, 2) NOT NULL ,  
  19.     [num6] [numeric](6, 0) NOT NULL ,  
  20.     [cost6] [numeric](5, 2) NOT NULL   
  21. ON [PRIMARY]  
  22. GO  
  23.  
  24.  

 

存储过程设计   下载

代码中有详细的解释,都是作者亲自编写,欢迎提出建议。
 

 
 
  1. ------------------------------------------------  
  2. ----------Author nileader-----------------------  
  3. ----------Date 2010/04/24-----------------------  
  4. ------------------------------------------------  
  5.  
  6. ALTER PROC pro_ProductSM  
  7.  
  8.     --    ------------参数声明  
  9. @SorM  char(2),  --表征当前业务是进货还是出售 S--进货 M--出售  
  10. @pId   nvarchar(20),  --表征操作的商品id  
  11.  
  12. @marketPrice nvarchar(10), --如果当前的业务是M,那么这个参数有效, 表示这次出售的价格  
  13. @marketNum   nvarchar(10), --如果当前的业务是M,那么这个参数有效,表示这次出售的数量  
  14.  
  15. @stockPrice  nvarchar(10), --如果当前的业务是S,那么这个参数有效,表示这次进货的成本单价  
  16. @stockNum    nvarchar(10)  --如果当前的业务是S,那么这个参数有效,表示这次进货的数量  
  17.  
  18.  
  19. AS 
  20. BEGIN 
  21.     DECLARE   
  22.      @stockNo   int,         --当前可以进货的仓库编号   仓库最大6个  
  23.      @marketNo  int,         --当前可以出售的仓库编号   仓库最大6个  
  24.      @updateSQL nvarchar(200) --一个待构造的sql update 语句  
  25.  
  26.     --选择操作业务  进货还是出售 S--进货 M--出售  
  27.  
  28.     --以下是进货操作  
  29. IF @SorM = 'S' 
  30.  BEGIN 
  31.  --让用户知道自己在干什么  
  32.  PRINT '提示信息:你即将以成本单价为'+@stockPrice+',进货一种编号为'+@pId
  33. +'的东西'+@stockNum+'件'   
  34.  
  35. --取出当前可以进货的编号  
  36.  SELECT @stockNo=stockNo, @marketNo=marketNo 
  37. FROM ProductSM WHERE pId=@pId    
  38.  
  39.   --判断是否可以继续进货  
  40.      IF @stockNo >=7    --不能继续进货了  
  41.         BEGIN 
  42.         PRINT '所有仓库已经有货,不能再继续进货了' 
  43.         END 
  44.      ELSE            --还能继续进货      1 <= @stockNo <=6  
  45.             BEGIN 
  46.         PRINT '开始更新数据库中的'+@pId  
  47.  
  48.         -- 构造出要更新的num和cost字段, 拼装成sql语句                 
  49.         DECLARE 
  50.          @_numx  nvarchar(10)    ,   --要更新的num号  
  51.          @_costx nvarchar(10)        --要更新的cost号  
  52.                   
  53.         SET   @_numx      = 'num'  + CONVERT(nvarchar(10),@stockNo)  
  54.         SET   @_costx     = 'cost' + CONVERT(nvarchar(10),@stockNo)
  55. SET     @updateSQL  ='UPDATE ProductSM SET '+@_numx+'='+@stockNum+', '
  56. +@_costx+'='+@stockPrice+', stockNo=stockNo+1 WHERE pId='+@pId  
  57.         EXEC(@updateSQL);  
  58.                   
  59.   --  如果之前所有的仓库都是空的,
  60. -- 那么marketNo=0,即没有指向任何可以出售的仓库,  
  61.         --  那么现在要让他指向第一个仓库  
  62.         IF @marketNo = 0  
  63.           BEGIN 
  64.             UPDATE ProductSM SET marketNo = 1 WHERE pId = @pId  
  65.           END 
  66.  
  67.       --让用户知道自己在干了什么  
  68.       PRINT '提示信息:你成功地以成本单价为'+@stockPrice
  69. +',进货了一种编号为'+@pId+'的东西'+@stockNum+'件'      
  70.                    
  71.       END       
  72.  
  73.        END 
  74.     -- =======以上是进货操作  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.     -- 以下是出售操作  
  82.     IF @SorM = 'M' 
  83.        BEGIN 
  84.             --让用户知道自己在干什么  
  85.         PRINT '提示信息:你即将以单价为 '+@marketPrice+' 出售一种编号为 '
  86. +@pId+' 的东西 '+@marketNum+'件'    
  87.  
  88.         DECLARE 
  89.             --   各个仓库现在的数量  
  90.             @num1       numeric(6),             --第1个仓库当前的数量  
  91.             @num2       numeric(6),             --第2个仓库当前的数量  
  92.             @num3       numeric(6),             --第3个仓库当前的数量  
  93.             @num4       numeric(6),             --第4个仓库当前的数量  
  94.             @num5       numeric(6),             --第5个仓库当前的数量  
  95.             @num6       numeric(6),             --第6个仓库当前的数量  
  96.             @totalNum   numeric(7),             --现在所有仓库中的数量和  
  97.  
  98.             @cost1      numeric(5,2),               --第1个仓库当前的成本  
  99.             @cost2      numeric(5,2),               --第2个仓库当前的成本  
  100.             @cost3      numeric(5,2),               --第3个仓库当前的成本  
  101.             @cost4      numeric(5,2),               --第4个仓库当前的成本  
  102.             @cost5      numeric(5,2),               --第5个仓库当前的成本  
  103.             @cost6      numeric(5,2)                --第6个仓库当前的成本  
  104.               
  105.  
  106.      -- 如果marketNo 大于stockNo 终止  
  107.      --取出当前可以出售的编号和进货编号  
  108.      SELECT @marketNo=marketNo, @stockNo = stockNo 
  109. FROM ProductSM WHERE pId=@pId   
  110.      IF @marketNo > @stockNo  
  111.            BEGIN      
  112.             PRINT '出售编号大于进货编号,怎么可能?我得去仓库看看了。' 
  113.            END 
  114.         ELSE 
  115.            BEGIN 
  116.             PRINT '仓库概况:当前进货编号为'+CAST(@stockNo AS nvarchar)
  117. +' 出售编号为'+CAST(@marketNo AS nvarchar)  
  118.  
  119.             --   统计出现在所有的库存量,用来检测这次出售交易是否超过了所有仓库的供给量  
  120.                 SELECT @num1=num1,@cost1=cost1, @num2=num2,@cost2=cost2,
  121.  @num3=num3,@cost3=cost3, @num4=num4,@cost4=cost4, 
  122. @num5=num5,@cost5=cost5, @num6=num6,@cost6=cost6   
  123.                 FROM ProductSM WHERE pId=@pId         
  124.       
  125.         SET @totalNum = @num1 + @num2 + @num3 + @num4 + @num5+ @num6  
  126.  
  127.         --如果现在的所有数量都不能满足你的要求,那就只好说再见了  
  128.         IF @totalNum < @marketNum  
  129.             BEGIN 
  130.                 print '不好意思,你的需求过大,交易失败' 
  131.             END 
  132.         ELSE IF @totalNum >= @marketNum  
  133.           BEGIN 
  134.                     --取出当前可以出售的编号  
  135.             SELECT @marketNo=marketNo FROM ProductSM WHERE pId=@pId       
  136.  
  137.              -- 从当前可以出售的开始,即@marketNo开始一个一个卖,知道满足marketNum需求  
  138.            DECLARE   
  139.                       
  140.               --是否完成交易,1表示完成,0表示没有完成,               
  141.            --这个标识用来表示在一个一个仓库卖的过程中,是否可以满足需求,终止此次交易  
  142.                     @flag   int           
  143.                     SET     @flag = 0    
  144.             DECLARE   
  145.             @thisWant   numeric(6), -- 现在还要的需求    
  146.             @thisNum    numeric(6), -- 现在所在的仓库有多少货  
  147.             @thisCost   numeric(5,2)    -- 现在所在的仓库的成本  
  148.             SET @thisWant = @marketNum  
  149.  
  150.             WHILE @flag = 0   
  151.             BEGIN   
  152.                         --取出当前可以进货的编号  
  153.             SELECT @marketNo=marketNo FROM ProductSM WHERE pId=@pId       
  154.                       
  155.             IF      @marketNo = 1     
  156.                         BEGIN    
  157.                           SET @thisNum = @num1    
  158.                           SET @thisCost = @cost1   
  159.                           SET @_numx ='num1'   
  160.                           SET @_costx = 'cost1'   
  161.                         END 
  162.             ELSE IF @marketNo = 2     
  163.                           BEGIN    
  164.                           SET @thisNum = @num2    
  165.                           SET @thisCost = @cost2   
  166.                           SET @_numx ='num2'   
  167.                           SET @_costx = 'cost2'   
  168.                         END 
  169.             ELSE IF @marketNo = 3     
  170.                           BEGIN    
  171.                            SET @thisNum = @num3    
  172.                            SET @thisCost = @cost3   
  173.                            SET @_numx ='num3'   
  174.                            SET @_costx = 'cost3'   
  175.                           END 
  176.             ELSE IF @marketNo = 4     
  177.                           BEGIN    
  178.                            SET @thisNum = @num4    
  179.                            SET @thisCost = @cost4   
  180.                            SET @_numx ='num4'   
  181.                            SET @_costx = 'cost4'   
  182.                           END 
  183.             ELSE IF @marketNo = 5     
  184.                            BEGIN    
  185.                             SET @thisNum = @num5    
  186.                             SET @thisCost = @cost5   
  187.                             SET @_numx ='num5'   
  188.                             SET @_costx = 'cost5'   
  189.                            END 
  190.             ELSE IF @marketNo = 6     
  191.                            BEGIN    
  192.                             SET @thisNum = @num6    
  193.                             SET @thisCost = @cost6   
  194.                             SET @_numx ='num6'   
  195.                             SET @_costx = 'cost6'   
  196.                            END 
  197.      
  198.                          DECLARE @money numeric(5,2)      --  盈利  
  199.                       
  200.                           --判断这个仓库是否可以满足这个交易的需求  
  201.                       
  202.               --如果这个仓库比需求大,那么出售marketNum件商品就ok了  
  203.              IF  @thisWant < @thisNum  
  204.                 BEGIN 
  205.                 PRINT '提示信息:本次交易以 '+@marketPrice+' 出售一种成本为'
  206. +CAST(@thisCost AS nvarchar)+'号为'+@pId+' 的东西 '
  207. +CONVERT(nvarchar(6),@thisWant)+'件' 
  208.                                   
  209.               -- 算一下赚了多少钱  
  210.                                   
  211.              SET @money = (@marketPrice - @thisCost) * @thisWant                                  
  212.                  PRINT '算一下赚了多少钱:' +CAST(@money AS nvarchar)  
  213.       
  214.              --更新数据库中的仓库信息  
  215.              SET @updateSQL ='UPDATE ProductSM SET '+@_numx+'='
  216. +CAST(@_numx AS nvarchar)+'-'
  217. +CAST(@thisWant AS nvarchar)+' WHERE pId='+@pId  
  218.              EXEC(@updateSQL);  
  219.  
  220.              --做一些收尾工作  
  221.              SET @thisWant = 0          --都满足需求了,肯定置为0了  
  222.              SET @flag = 1      --表示已经完成了  
  223.             END 
  224.  
  225.              --如果这个仓库和需求一样,那么出售这个仓库的所有,并把marketNo指向下一个仓库  
  226.             ELSE IF  @thisWant = @thisNum  
  227.               BEGIN 
  228.                PRINT '提示信息:本次交易以 '+@marketPrice+' 出售一种成本为'
  229. +CAST(@thisCost AS nvarchar)
  230. +'号为'+@pId+' 的东西 '+CONVERT(nvarchar(6),@thisWant)+'件' 
  231.                                   
  232.                -- 算一下赚了多少钱  
  233.               
  234.                SET @money = (@marketPrice - @thisCost) * @thisWant                                
  235.                PRINT '算一下赚了多少钱:' +CAST(@money AS nvarchar)  
  236.                                   
  237.  
  238.                --更新数据库中的仓库信息  
  239.                SET @updateSQL   ='UPDATE ProductSM SET marketNo = marketNo + 1,'
  240. +@_numx+'=0,'+@_costx+'=0 WHERE pId='+@pId  
  241.                EXEC(@updateSQL);  
  242.  
  243.                --做一些收尾工作  
  244.                SET @thisWant = 0        --都满足需求了,肯定置为0了  
  245.                SET @flag = 1        --表示已经完成了  
  246.               END 
  247.  
  248.  
  249.               --如果这个仓库比需求小,那么出售这个仓库的所有,并把marketNo指向下一个仓库,继续下一个循环  
  250.               ELSE IF  @thisWant > @thisNum  
  251.                 BEGIN 
  252.                   PRINT '提示信息:本次交易以 '+@marketPrice+' 出售一种成本为'
  253. +CAST(@thisCost AS nvarchar)
  254. +'号为'+@pId+' 的东西 '+CONVERT(nvarchar(6),@thisNum)+'件' 
  255.                                   
  256.                   -- 算一下赚了多少钱  
  257.               
  258.                   SET @money = (@marketPrice - @thisCost) * @thisNum                              
  259.                   PRINT '算一下赚了多少钱:' +CAST(@money AS nvarchar)  
  260.                                   
  261.                   --更新数据库中的仓库信息  
  262.                  SET @updateSQL ='UPDATE ProductSM SET marketNo = marketNo + 1,'
  263. +@_numx+ WHERE pId=''=0,'+@_costx+'=0+@pId  
  264.                  EXEC(@updateSQL);  
  265.  
  266.                   --做一些收尾工作  
  267.                   SET @thisWant = @thisWant - @thisNum    --都满足需求了,肯定置为0了  
  268.  
  269.                  END 
  270.  
  271.  
  272.             END   
  273.  
  274.  
  275.                   
  276.              END 
  277.         END   
  278.        END 
  279.     -- ========以上是出售操作  
  280.  
  281. END 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值