本文是我在前一篇文章提到的关于先进先出存储过程,针对Oracle 9i 的修改版,基本思路一致,只是修改了关键字使用方法。
有关数据库和存储过程的设计,请参阅使用存储过程实现进销存系统中的先进先出 算法(1)——数据库与存储过程设计
使用Sql Server? 前往。
点击下载Oracle 9i 存储过程 下载
- ------------------------------------------------
- ----------Author nileader----------23-------------
- ----------Date 2010/04/24-----------------------
- ------------------------------------------------
- CREATE OR REPLACE PROCEDURE pro_ProductSM(
- SorM IN char, --表征当前业务是进货还是出售 S--进货 M--出售
- pId IN productsm.pid%type, --表征操作的商品id
- marketPrice IN nvarchar2, --如果当前的业务是M,那么这个参数有效, 表示这次出售的价格
- marketNum IN nvarchar2, --如果当前的业务是M,那么这个参数有效,表示这次出售的数量
- stockPrice IN nvarchar2, --如果当前的业务是S,那么这个参数有效,表示这次进货的成本单价
- stockNum IN nvarchar2 --如果当前的业务是S,那么这个参数有效,表示这次进货的数量
- ) IS
- BEGIN
- --定义变量
- DECLARE
- stockNo int; -- 当前可以进货的仓库编号 仓库最大6个
- marketNo int; -- 当前可以出售的仓库编号 仓库最大6个
- updateSQL nvarchar2(200); -- 一个待构造的sql update 语句
- numx nvarchar2(10); --要更新的num号
- costx nvarchar2(10); --要更新的cost号
- -- 各个仓库现在的数量
- 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个仓库当前的成本
- flag int; --是否完成交易,1表示完成,0表示没有完成,
- --这个标识用来表示在一个一个仓库卖的过程中,
- --是否可以满足需求,终止此次交易
- thisWant numeric(6); -- 现在还要的需求
- thisNum numeric(6); -- 现在所在的仓库有多少货
- thisCost numeric(5, 2); -- 现在所在的仓库的成本
- money numeric(5, 2); -- 盈利
- --------- 选择操作业务 进货还是出售 S--进货 M--出售 ---------
- -----------------------以下是进货操作------------------
- BEGIN
- --0
- IF SorM = 'S' THEN
- --2
- BEGIN
- --1
- --让用户知道自己在干什么
- DBMS_OUTPUT.PUT_LINE('INFO:You will buy somethings-------price is' ||
- stockPrice || '---nums is ' || stockNum ||
- '---pid is ' || pId);
- --取出当前可以进货的编号
- SELECT stockNo, marketNo
- INTO stockNo, marketNo
- FROM ProductSM
- WHERE pId = pId;
- --判断是否可以继续进货
- IF stockNo >= 7 THEN
- --3 --不能继续进货了
- DBMS_OUTPUT.PUT_LINE('All storages have full, can not buy!');
- --还能继续进货 1 <= stockNo <=6
- ELSE
- BEGIN
- --4
- DBMS_OUTPUT.PUT_LINE('INFO:BEGIN UPDATE THE DB WHERE PID IS' || pId);
- -- --构造出要更新的num和cost字段, 拼装成sql语句---
- numx := 'num' || TO_CHAR(stockNo);
- costx := 'cost' || stockNo;
- updateSQL := 'UPDATE ProductSM SET ' || numx || '=' || stockNum || ', ' ||
- costx || '=' || stockPrice ||
- ', stockNo=stockNo+1 WHERE pId=' || pId;
- EXECUTE IMMEDIATE TO_CHAR(updateSQL);
- -- 如果之前所有的仓库都是空的,那么marketNo=0,
- -- 即没有指向任何可以出售的仓库,那么现在要让他指向第一个仓库
- IF marketNo = 0 THEN
- --5
- BEGIN
- updateSQL := 'UPDATE ProductSM SET marketNo = 1 WHERE pId =' || pId;
- EXECUTE IMMEDIATE TO_CHAR(updateSQL);
- END;
- END IF; --5
- --让用户知道自己完成了什么工作
- DBMS_OUTPUT.PUT_LINE('INFO:You buy something successfully!!'
- ||'-------------stockPrice is' ||
- stockPrice || ',---pid is ' || pId ||
- '----stockNum is' || stockNum);
- END; --4
- END IF; --3
- END; --1
- ----------------------------------以上是进货操作----------------------------
- -----------------------------------以下是出售操作----------------------------
- ELSIF SorM = 'M' THEN
- --6
- BEGIN
- --7
- --让用户知道自己在干什么
- DBMS_OUTPUT.PUT_LINE('INFO:You will sell somethings-------price is' ||
- marketPrice || '---nums is ' || marketNum ||
- '---pid is ' || pId);
- -- 如果marketNo 大于stockNo 终止
- --取出当前可以出售的编号和进货编号
- SELECT stockNo, marketNo
- INTO stockNo, marketNo
- FROM ProductSM
- WHERE pId = pId;
- IF marketNo > stockNo THEN
- --10
- BEGIN
- DBMS_OUTPUT.PUT_LINE('出售编号大于进货编号,怎么可能?我得去仓库看看了。');
- END;
- ELSE
- BEGIN
- --11
- --仓库概况
- DBMS_OUTPUT.PUT_LINE('Storages INFO:----stockNo is' ||
- TO_CHAR(stockNo) || ' -------marketNo is' ||
- TO_CHAR(marketNo));
- -- 统计出现在所有的库存量,用来检测这次出售交易是否超过了所有仓库的供给量
- SELECT num1,
- cost1,
- num2,
- cost2,
- num3,
- cost3,
- num4,
- cost4,
- num5,
- cost5,
- num6,
- cost6
- INTO num1,
- cost1,
- num2,
- cost2,
- num3,
- cost3,
- num4,
- cost4,
- num5,
- cost5,
- num6,
- cost6
- FROM ProductSM
- WHERE pId = pId;
- totalNum := num1 + num2 + num3 + num4 + num5 + num6;
- --如果现在的所有数量都不能满足你的要求,那就只好说再见了
- IF totalNum < marketNum THEN
- --12
- DBMS_OUTPUT.PUT_LINE('不好意思,你的需求过大,交易失败');
- ELSE
- BEGIN
- --13
- --取出当前可以出售的编号
- SELECT marketNo
- INTO marketNo
- FROM ProductSM
- WHERE pId = pId;
- -- 从当前可以出售的开始,即@marketNo开始一个一个卖,直到满足marketNum需求
- flag := 0;
- thisWant := marketNum;
- WHILE flag = 0 LOOP
- --14
- --取出当前可以进货的编号
- SELECT marketNo
- INTO marketNo
- FROM ProductSM
- WHERE pId = pId;
- IF marketNo = 1 THEN
- --15
- BEGIN
- thisNum := num1;
- thisCost := cost1;
- numx := 'num1';
- costx := 'cost1';
- END;
- ELSIF marketNo = 2 THEN
- BEGIN
- thisNum := num2;
- thisCost := cost2;
- numx := 'num2';
- costx := 'cost2';
- END;
- ELSIF marketNo = 3 THEN
- BEGIN
- thisNum := num3;
- thisCost := cost3;
- numx := 'num3';
- costx := 'cost3';
- END;
- ELSIF marketNo = 4 THEN
- BEGIN
- thisNum := num4;
- thisCost := cost4;
- numx := 'num4';
- costx := 'cost4';
- END;
- ELSIF marketNo = 5 THEN
- BEGIN
- thisNum := num5;
- thisCost := cost5;
- numx := 'num5';
- costx := 'cost5';
- END;
- ELSIF marketNo = 6 THEN
- BEGIN
- thisNum := num6;
- thisCost := cost6;
- numx := 'num6';
- costx := 'cost6';
- END;
- END IF; --15
- --判断这个仓库是否可以满足这个交易的需求
- --如果这个仓库比需求大,那么出售marketNum件商品就ok了
- IF thisWant < thisNum THEN
- --17
- BEGIN
- --18
- DBMS_OUTPUT.PUT_LINE('INFO:you sell something-------marketPrice is ' ||
- marketPrice || ' ----cost is' ||
- TO_CHAR(thisCost) ||
- '----pid is' || pId ||
- '------num is' ||
- TO_CHAR(thisWant));
- -- 算一下赚了多少钱
- money := (marketPrice - thisCost) * thisWant;
- DBMS_OUTPUT.PUT_LINE('money you gain is:' ||
- TO_CHAR(money));
- --更新数据库中的仓库信息
- updateSQL := 'UPDATE ProductSM SET ' || numx || '=' ||
- TO_CHAR(numx) || '-' ||
- TO_CHAR(thisWant) || ' WHERE pId=' || pId;
- EXECUTE IMMEDIATE TO_CHAR(updateSQL);
- --做一些收尾工作
- thisWant := 0; --都满足需求了,肯定置为0了
- flag := 1; --表示已经完成了
- END; --18
- ELSIF thisWant = thisNum THEN
- --20
- BEGIN
- --21
- DBMS_OUTPUT.PUT_LINE('INFO:you sell something-------marketPrice is ' ||
- marketPrice || ' ----cost is' ||
- TO_CHAR(thisCost) ||
- '----pid is' || pId ||
- '------num is' ||
- TO_CHAR(thisWant));
- -- 算一下赚了多少钱
- money := (marketPrice - thisCost) * thisWant;
- DBMS_OUTPUT.PUT_LINE('money you gain is:' ||
- TO_CHAR(money));
- --更新数据库中的仓库信息
- updateSQL := 'UPDATE ProductSM SET marketNo = marketNo + 1,' || numx +
- '=0,' || costx || '=0 WHERE pId=' || pId;
- EXECUTE IMMEDIATE TO_CHAR(updateSQL);
- --做一些收尾工作
- thisWant := 0; --都满足需求了,肯定置为0了
- flag := 1; --表示已经完成了
- END; --21
- ELSE
- --23
- BEGIN
- --22
- DBMS_OUTPUT.PUT_LINE('INFO:you sell something-------marketPrice is ' ||
- marketPrice || ' ----cost is' ||
- TO_CHAR(thisCost) ||
- '----pid is' || pId ||
- '------num is' ||
- TO_CHAR(thisNum));
- -- 算一下赚了多少钱
- money := (marketPrice - thisCost) * thisNum;
- DBMS_OUTPUT.PUT_LINE('money you gain is:' ||
- TO_CHAR(money));
- --更新数据库中的仓库信息
- updateSQL := 'UPDATE ProductSM SET marketNo = marketNo + 1,' || numx +
- '=0,' || costx + '=0 WHERE pId=' || pId;
- EXECUTE IMMEDIATE TO_CHAR(updateSQL);
- --做一些收尾工作
- thisWant := thisWant - thisNum;
- END; --22
- END IF; --17
- END LOOP; --14
- END; --13
- END IF; --12
- END; --11
- END IF; --10
- END; --7
- END IF; --2
- END; --0
- END;