库存数量管理方案一:基于SQL存储过程和MERGE(结合活字格案例)

时间:2024-03-11 08:58:56

库存更新是ERP系统的基本功能,一般包括以下动作:
1、以库位编号和商品编号查询库存表,如果查询不到,则添加一行库存信息,如:(出入库)库位编号/(出入库)商品编号/(出入库)+或-数量
2、以库位编号和商品编号查询库存表,如果查询到,则更新查询到的库存信息,如:(库存表)数量=(库存表)数量+或-(出入库)数量

很奇怪活字格的数据表操作命令,不提供以下功能:(1)更新(如果没有就添加);(2)字段值,一不能取得库存表的值,二不能设置条件。所以论坛里存在着好几个版本的库存更新方案,比如:
1、官方用到的页面处理方法,因为比较违反我所认知的常识逻辑(之前有接触过很多类似平台,这事情就应该放到服务端去干,或者是固有的思维吧),这个方法具体实现没有细看。也有很多同仁说,数据调到页面处理,如果是高并发情况,调出数据后,如果数据源的数据已变更,怎么办?这样的问题,是很容易想到的。(但好像什么时候听梁老湿说有方案可以在页面处理的时候避免高并发数据不一致的情况)
2、视图法,就是所有的出入库操作(包括盘点等),用select和union all做成视图,然后出入库视图的基本上,再用group by做库存计算。这个方案,可以避免方案1数据不一致的问题。但但但,这是个虚拟库存表呀,所以你怎么样都会感觉它虚,另一个就是很快会碰到的效率问题。如果是有POS系统的,就算一年销售50万件货吧,产生的数据量大概就要到一两百万条了,而且还要在视图基础上再做两到三层的视图(数据库效率论里面一般都会说要尽量避免多层视图),可见以后麻烦会有多大。另外,和库存关联比较大的一个应用WMS,要涉及到比较复杂的库存条件判断和计算(比如库位锁定等),用这个方法也基本上非常难解决。

所以,思来想去,还是要老老实实做累计库存表,而要用累计库存表,又不能在页面端处理数据,就只能用存储过程了。所以到这里的时候,我就直接放弃内置数据库,然后开始学习SQL。下面我介绍的方法,就是基于外置数据库(sqlserver)和MERGE。

现在活字格调用存储过程非常的方便,有了存储过程,意味的系统设计的灵活性翻了一片天,因为你可以直接用SQL了。用SQL,不仅仅在功能上,还有在案例资源上,那就不是活字格这块天地了,而是整个数据库的天地,想实现啥功能,搜一搜,基本上能找到方案。(另一个类似功能是JS,暂且不表)。

话题拉回来。在数据库端实现库存更新,基本上有两个思路,一是用IF和EXIST,循环判断,然后根据判断结果执行UPDATE或者INSERT;二就是用强大的MERGE,MERGE可以说是专门为这种更新而生的。我直接选个这个方案。(官方关于MERGE的应用说明)https://docs.microsoft.com/zh-cn ... iew=sql-server-2017

用MERGE,有两个表,一是目标表,这里就是库存表;二是源表,这里就是业务表单,如出库、入库等。在数据库端,用这个源表的话,你要做一下筛选,MERGE支持源表的子查询。所以结合活字格的存储过程,你就要在页面,将主表的单号做为参数传递给存储过程,然后源表用子查询WHERE一下,就解决源表的问题了。另外,MERGE的UPDAGE和INSERT是支持标量子查询和CASE的,这就给更复杂的条件判断留下了可能(因为现在的系统还没涉及到,所以还没详细研究)。好了,下面亮代码:

1、存储过程(这个是增加,同时要有一个反向的):
<ignore_js_op>

2、页面调用存储过程
<ignore_js_op>

3、按钮的控制(页面的按钮支持正向和反向,如上图,我是根据按钮单元格的值来调用正向和反向的存储过程)。活字格真得很灵活呀,可以直接根据表单状态值来直接更新按钮(设置单元格属性,如背景和值等)。

这样,就能够实现一个严谨的库存更新的业务逻辑了。