SQL Server 用触发器实现库存的先进先出(有退货)

今天碰到个论坛问题关于库存的先进先出,写成博客以免以后搜不到。
限制:
1)进仓表、出仓表只能一次插入一条,多条触发器没有对应。
2)退货没有指定批次,是按最近原则自动匹配的。

表结构和触发器

CREATE TABLE 进仓表(
    id int identity(1,1),
    日期 datetime,
    产品 varchar(10),
    数量 int,
    单价 money
)
GO
CREATE TABLE 出仓表(
    id int identity(1,1),
    日期 datetime,
    产品 varchar(10),
    数量 int,
    金额 money
)
GO
CREATE TABLE 库存表(
    id int, -- = 进仓表.id,表示批次
    产品 varchar(10),
    入库数量 int,
    库存数量 int,
    单价 money
)
GO
CREATE TRIGGER tr_进仓表 ON 进仓表
AFTER INSERT
AS
    DECLARE @id int
    DECLARE @pno varchar(10)
    DECLARE @qty int
    DECLARE @price money

    DECLARE @batchNo int

    SELECT @id = id,
           @pno = 产品,
           @qty = 数量,
           @price = 单价
      FROM inserted

    IF @qty >=0 -- 正常入库

        INSERT INTO 库存表
        SELECT @id, @pno, @qty, @qty, @price
        
    ELSE -- 退货
    BEGIN


        SELECT @batchNo = MAX(id)
          FROM 库存表
         WHERE 产品 = @pno
           AND 单价 = @price
           AND (库存数量 + @qty) >=0

        IF @batchNo IS NULL
        BEGIN
            PRINT '没有可退货的库存'
            ROLLBACK TRAN
            RETURN
        END

        UPDATE 库存表
           SET 入库数量 = 入库数量 + @qty,
               库存数量 = 库存数量 + @qty
         WHERE id = @batchNo

    END
GO

CREATE TRIGGER tr_出仓表 ON 出仓表
AFTER INSERT
AS
    DECLARE @id int
    DECLARE @pno varchar(10)
    DECLARE @totalQty int
    DECLARE @amount money

    DECLARE @batchNo int
    DECLARE @batchQty int
    DECLARE @batchPrice money
    DECLARE @batchUseQty int

    SET @amount = 0

    SELECT @id = id,
           @pno = 产品,
           @totalQty = 数量
      FROM inserted

    IF @totalQty >=0 -- 正常出库
    BEGIN

        WHILE @totalQty > 0
        BEGIN

            SELECT TOP 1
                   @batchNo = id,
                   @batchQty = 库存数量,
                   @batchPrice = 单价
              FROM 库存表
             WHERE 产品 = @pno
               AND 库存数量 > 0
          ORDER BY id

            IF @batchNo IS NULL
            BEGIN
                PRINT '库存不足'
                ROLLBACK TRAN
                RETURN
            END

            IF @batchQty >= @totalQty
                SET @batchUseQty = @totalQty
            ELSE
                SET @batchUseQty = @batchQty

            UPDATE 库存表
               SET 库存数量 = 库存数量 - @batchUseQty
             WHERE id = @batchNo

            SET @amount = @amount + @batchUseQty * @batchPrice
            SET @totalQty = @totalQty - @batchUseQty

        END

    END
    ELSE -- 退货
    BEGIN

        WHILE @totalQty < 0
        BEGIN

            SELECT TOP 1
                   @batchNo = id,
                   @batchQty = 入库数量 - 库存数量,
                   @batchPrice = 单价
              FROM 库存表
             WHERE 产品 = @pno
               AND 入库数量 > 库存数量
          ORDER BY id DESC

            IF @batchNo IS NULL
            BEGIN
                PRINT '没有可退货的库存'
                ROLLBACK TRAN
                RETURN
            END

            IF @batchQty >= ABS(@totalQty)
                SET @batchUseQty = ABS(@totalQty)
            ELSE
                SET @batchUseQty = @batchQty

            UPDATE 库存表
               SET 库存数量 = 库存数量 + @batchUseQty
             WHERE id = @batchNo

            SET @amount = @amount + @batchUseQty * @batchPrice
            SET @totalQty = @totalQty + @batchUseQty

        END

    END

    UPDATE 出仓表
       SET 金额 = @amount
     WHERE id = @id

GO

测试

INSERT INTO 进仓表(日期,产品,数量,单价) VALUES('2015-01-01','A',10,100)
SELECT * FROM 进仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  单价
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-01 00:00:00.000 A                   10                100.00

         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                   10          10                100.00

INSERT INTO 进仓表(日期,产品,数量,单价) VALUES('2015-01-02','A',4,120)
SELECT * FROM 进仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  单价
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-01 00:00:00.000 A                   10                100.00
          2 2015-01-02 00:00:00.000 A                    4                120.00

         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                   10          10                100.00
          2 A                    4           4                120.00

INSERT INTO 出仓表(日期,产品,数量)
 VALUES('2015-01-02','A',5)
SELECT * FROM 出仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  金额
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-02 00:00:00.000 A                    5                500.00


         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                   10           5                100.00
          2 A                    4           4                120.00

INSERT INTO 进仓表(日期,产品,数量,单价) VALUES('2015-01-03','A',-5,100)
SELECT * FROM 进仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  单价
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-01 00:00:00.000 A                   10                100.00
          2 2015-01-02 00:00:00.000 A                    4                120.00
          3 2015-01-03 00:00:00.000 A                   -5                100.00

         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                    5           0                100.00
          2 A                    4           4                120.00

INSERT INTO 进仓表(日期,产品,数量,单价) VALUES('2015-01-04','A',15,90)
SELECT * FROM 进仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  单价
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-01 00:00:00.000 A                   10                100.00
          2 2015-01-02 00:00:00.000 A                    4                120.00
          3 2015-01-03 00:00:00.000 A                   -5                100.00
          4 2015-01-04 00:00:00.000 A                   15                 90.00

         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                    5           0                100.00
          2 A                    4           4                120.00
          4 A                   15          15                 90.00

INSERT INTO 出仓表(日期,产品,数量)
 VALUES('2015-01-04','A',6)
SELECT * FROM 出仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  金额
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-02 00:00:00.000 A                    5                500.00
          2 2015-01-04 00:00:00.000 A                    6                660.00

         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                    5           0                100.00
          2 A                    4           0                120.00
          4 A                   15          13                 90.00

INSERT INTO 出仓表(日期,产品,数量)
 VALUES('2015-01-05','A',-3)
SELECT * FROM 出仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  金额
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-02 00:00:00.000 A                    5                500.00
          2 2015-01-04 00:00:00.000 A                    6                660.00
          3 2015-01-05 00:00:00.000 A                   -3                300.00

         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                    5           0                100.00
          2 A                    4           1                120.00
          4 A                   15          15                 90.00

INSERT INTO 出仓表(日期,产品,数量)
 VALUES('2015-01-07','A',10)
SELECT * FROM 出仓表
SELECT * FROM 库存表
GO

         id 日期                    产品              数量                  金额
----------- ----------------------- ---------- ----------- ---------------------
          1 2015-01-02 00:00:00.000 A                    5                500.00
          2 2015-01-04 00:00:00.000 A                    6                660.00
          3 2015-01-05 00:00:00.000 A                   -3                300.00
          4 2015-01-07 00:00:00.000 A                   10                930.00

         id 产品          入库数量    库存数量                  单价
----------- ---------- ----------- ----------- ---------------------
          1 A                    5           0                100.00
          2 A                    4           0                120.00
          4 A                   15           6                 90.00

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程介绍 仓库管理系统主要功能有采购入库,采购退货,销售出库,销售退货,仓库盘点,库存报表,Excel导入导出,按钮级权限控制及系统日志等功能,系统采用SpringBoot ,mybatis,easyui,ajax,mssql数据库等技术开发。提供所有源代码下载,系统功能完善,可直接运行。开发环境项目开发语言:SpringBoot ,mybatis,easyui,ajax,mssql数据库项目运行环境:jdk1.8及以上版本,tomcat8.0及以上版本,sql server2005及以上版本项目开发工具: 本项目开发工具是Intellij Idea课程目标掌握SpringBoot等技术,熟悉仓库管理系统主要功能,采购入库,采购退货,销售出库,销售退货,仓库盘点,系统报表,权限控制及日志等50多门JAVA系列全套课程,包括大一新生到大四毕业的所有JAVA系列技术专业课程,项目实战,商业项目等;基础课程:JAVA初级工程师: 1、计算机基础 2、HTML语言基础 3、C语言从入门到精通+贪吃蛇游戏 4、贪吃蛇游戏 5、SQL SERVER数据库基础 6、JAVA从入门到精通+推箱子游戏+QQ即时通讯软件 7、推箱子游戏; 8、仿QQ即时通讯软件;JAVA中级工程师: 9、SQLSERVER数据库高级 10、SQLSERVER从入门到精通(基础+高级) 11、JavaScript从入门到精通, 12、JSP从入门到精通+点餐系统, 13、JSP从入门到精通+在线视频学习教育平台, 14、JSP从入门到精通+大型电商平台; 15、XML从入门到精通, 16、数据结构(JAVA版),JAVA高级工程师: 17、Oracle数据库从入门到精通, 18、ajax+jquery从入门到精通, 19、EasyUI从入门到精通,SSH框架: 20、Struts2从入门到精通课程, 21、Hibernate从入门到精通课程, 22、Spring从入门到精通课程; 23、Echarts从入门到精通, 24、Excel基于POI的导入导出工作流框架: 25、Activiti流程框架从入门到精通 26、JBPM流程框架从入门到精通SSM框架: 27、MyBatis从入门到精通 28、Spring MVC从入门到精通 29、Spring Boot入门到精通 30、Spring Cloud入门到精通面试题: 31、职业生涯规划及面试题集锦商业项目: 32、微信公众号在线支付系统 33、微信生活缴费在线支付系统 34、支付宝生活缴费在线支付系统 35、在线考试系统 36、人脸识别智能考试系统(人工智能AI) 37、仓库管理及质量追溯系统 38、房屋出租管理系统APP(身份证识别) 39、手机订餐管理系统, 40、CRM客户关系管理系统 41、大型房地产CRM销售管理系统 42、CMPP2,CMPP3移动网关系统 43、仓库管理系统(SpringBoot) 44、影院在线售票系统(仿猫眼电影)人工智能: 45、人脸识别在线考试系统 46、人脸识别系统项目实战 47、车牌识别停车场管理系统 48、身份证识别系统项目实战 49、营业执照识别系统项目实战 50、名片识别管理系统

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值