• ORACLE 中报ORA30926 无法在源表中获得稳定的行的处理


    在库存处理的业务中有这么一个场景,一张处方划价单进行库存扣减处理,如果此单据同一商品有两行以上,同时扣减同一行库存记录,使用MERGE INTO批量更新是就会报错:ORA-30926 无法在源表中获得稳定的行。

    库存表T_DRUGSTORE_DRUG_STOCK_TEMP 的记录

    处方划价单T_OPD_QUOTN的记录(待出库信息),注意:这里 1、2行的同时要扣减了库存表中ID是93498记录的库存。 

      以上情况使用以下语句会因为批量更新时被更新的表记录出现了一对多行匹配导致异常错误

     

    在扣减库存前要确保匹配行不能出现一对多,以下实现这里主要四点作为了解

      1、使用 COUNT(distinct STOCK_ID) 求得单据药品涉及到的库存记录数。

      2、MERGE INTO中的USING子查询使用了分组在库存扣减前对出库记录按照药品库存的ID进行分组求和待出库数量。

      3、更新库存的时候使用 WHERE a.QUANTITY>=b.BASE_QUANTITY 仅更新库存足够的记录,后面通过 SQL%ROWCOUNT!=tn_rowcount 验证是否期待的库存记录都被更新了。

      4、这样处理批量更新比逐行循环更新处理高效。

    --取得出库单药品品种数和待出库总数量
    SELECT COUNT(distinct STOCK_ID) AS rowcount,NVL(SUM(QUANTITY),0) AS quantity
      INTO tn_rowcount,tn_quantity
      FROM T_OPD_QUOTN WHERE HOSPITAL_ID=ow_hosid AND ORDER_WRITE_ID=writeId;
    IF ow_count!=tn_quantity THEN
      mess:='医嘱药品数量'||ow_count||'与划价单数量合计'||tn_quantity||'不符!';
      RETURN;
    END IF;
    --进行库存扣减处理,更新划价单对应批次结存数量
    MERGE INTO T_DRUGSTORE_DRUG_STOCK_TEMP a
      USING (SELECT STOCK_ID,sum(BASE_QUANTITY) as BASE_QUANTITY FROM T_OPD_QUOTN
        WHERE HOSPITAL_ID=ow_hosid AND ORDER_WRITE_ID=writeId GROUP BY STOCK_ID) b ON (a.ID=b.STOCK_ID)
      WHEN MATCHED THEN UPDATE SET a.QUANTITY=a.QUANTITY-b.BASE_QUANTITY,UPDATE_OPER=operateId,UPDATE_DATE=SYSDATE WHERE a.QUANTITY>=b.BASE_QUANTITY;
    IF SQL%ROWCOUNT!=tn_rowcount THEN
    mess:='临时库存更新'||SQL%ROWCOUNT||'行,与划价记录行'||tn_rowcount||'不符,操作无效!';
    RETURN;
    END IF;
    凡哥,别他妈吹牛逼了
  • 相关阅读:
    富文本编辑器 ueditor
    防抖和节流 lodash插件
    lodash
    awesome
    怎么在移动端模拟pc端进行web开发调试日志
    添加水印
    node.js取参四种方法req.body,req.params,req.param,req.body
    插件包
    python——Scrapy框架简介、内置选择器、管道文件、爬虫模块中的spider类
    python——BeautifulSoup4解析器,JSON与JsonPATH,多线程爬虫,动态HTML处理
  • 原文地址:https://www.cnblogs.com/sdlz/p/15636613.html
Copyright © 2020-2023  润新知