Sql 在更新期间从旧表和最终表中选择值

Sql 在更新期间从旧表和最终表中选择值,sql,db2,Sql,Db2,我写了一个UPDATE语句,它将采用@CHANGE正整数值或负整数值,并更新该类型商品的当前库存 UPDATE ITEM_INVENTORY SET CURRENT_INVENTORY = MAX(CURRENT_INVENTORY + @CHANGE, 0), LAST_UPD_TSTAMP = CURRENT_TIMESTAMP, LAST_UPD_SOURCE = @SOURCE WHERE LOCATION = @LOCATION AND

我写了一个UPDATE语句,它将采用@CHANGE正整数值或负整数值,并更新该类型商品的当前库存

UPDATE ITEM_INVENTORY
SET    CURRENT_INVENTORY = MAX(CURRENT_INVENTORY + @CHANGE, 0),
       LAST_UPD_TSTAMP = CURRENT_TIMESTAMP,
       LAST_UPD_SOURCE = @SOURCE
WHERE  LOCATION = @LOCATION
       AND ITEM_TYPE = @ITEM_TYPE;
我想知道在运行此更新之前和之后,当前的库存是什么。是否有办法选择当前库存的旧表和最终表值

我想显示一条消息,内容是{location}清单从{old}更改为{new}。我可以使用单独的SELECT来获取旧值/当前值,在代码中进行计算,然后更新表中的行。我相信这可能会受到竞争条件的影响,因为第一次选择不会锁定行,所以我尝试在单个查询中执行此操作

我认为我不能同时选择旧的和最终的,因此我认为我的最佳解决方案是:

从旧表中选择value,并复制CASE语句中的逻辑以派生新值 从旧表中选择值,并选择同一事务中的新值,因为我的更新已锁定该行
是否有更好/正确的方法来完成此任务?

更新内联视图而不是表:

SELECT CURRENT_INVENTORY, CURRENT_INVENTORY_OLD
FROM FINAL TABLE(
  UPDATE (SELECT *, CURRENT_INVENTORY AS CURRENT_INVENTORY_OLD 
          FROM ITEM_INVENTORY)
  SET CURRENT_INVENTORY = CASE 
                             WHEN CURRENT_INVENTORY + @CHANGE < 0 THEN 0
                             ELSE CURRENT_INVENTORY + @CHANGE
                           END,
       LAST_UPD_TSTAMP = CURRENT_TIMESTAMP,
       LAST_UPD_SOURCE = @SOURCE
  WHERE LOCATION = @LOCATION
    AND ITEM_TYPE = @ITEM_TYPE
);

正在更新内联视图而不是表:

SELECT CURRENT_INVENTORY, CURRENT_INVENTORY_OLD
FROM FINAL TABLE(
  UPDATE (SELECT *, CURRENT_INVENTORY AS CURRENT_INVENTORY_OLD 
          FROM ITEM_INVENTORY)
  SET CURRENT_INVENTORY = CASE 
                             WHEN CURRENT_INVENTORY + @CHANGE < 0 THEN 0
                             ELSE CURRENT_INVENTORY + @CHANGE
                           END,
       LAST_UPD_TSTAMP = CURRENT_TIMESTAMP,
       LAST_UPD_SOURCE = @SOURCE
  WHERE LOCATION = @LOCATION
    AND ITEM_TYPE = @ITEM_TYPE
);

您可以对该SQL手册使用“从更新中选择”。 例如:


您可以对该SQL手册使用“从更新中选择”。 例如:


获取错误[42601][IBM][DB2]SQL0104N发现以下意外标记。预期的令牌可能包括:统计信息。我假设DB2可能不支持更新内联视图。@JeffBridgman可能添加别名会有所帮助:更新。。。我…还是会犯同样的错误。谢谢你的帮助!另一个答案似乎是正确的:您使用的是什么版本的Db2?上面的代码在DB2LUW11.1.3.3上适用。但是,另一个答案中的代码也可以工作,可能是z/OS 11的一个小错误。我认为SYSIBM.VERSION返回DSN11015根据这个错误得到了一个错误[42601][IBM][DB2]SQL0104N在下面发现了一个意外的令牌。预期的令牌可能包括:统计信息。我假设DB2可能不支持更新内联视图。@JeffBridgman可能添加别名会有所帮助:更新。。。我…还是会犯同样的错误。谢谢你的帮助!另一个答案似乎是正确的:您使用的是什么版本的Db2?上面的代码在DB2LUW11.1.3.3上适用。但是,另一个答案中的代码也可以工作,对于z/OS 11,可能是一个比较好的RDB2,我认为SYSIBM.VERSION返回DSN11015,根据这一点,我以前从未见过使用INCLUDE。工作完美;谢谢我以前从未见过INCLUDE的用法。工作完美;谢谢旁注:DB2允许使用MAX作为标量选择器,您不需要CASE,其他大多数都有一个等价的MAX。然而负库存实际上是零售业的一个问题,所以我有点担心你在做什么。这也使得你处理更新的顺序非常重要,或者你可以通过在库存进入系统之前出售库存来报告你没有的库存。@Clockwork Muse啊,MAX更好;这不适用于零售业,所以我们不需要与环境要求的相同级别的严格正确性。伟大的洞察力!因此,也可以添加WHERE CURRENT_INVENTORY MAXCURRENT_INVENTORY+@CHANGE,0,以避免在实际没有任何更改时更新行注意:DB2允许使用MAX作为标量选择器,而您不需要使用CASE,其他大多数都有一个等价的MAX。然而负库存实际上是零售业的一个问题,所以我有点担心你在做什么。这也使得你处理更新的顺序非常重要,或者你可以通过在库存进入系统之前出售库存来报告你没有的库存。@Clockwork Muse啊,MAX更好;这不适用于零售业,所以我们不需要与环境要求的相同级别的严格正确性。伟大的洞察力!因此,也可以添加WHERE CURRENT_INVENTORY MAXCURRENT_INVENTORY+@CHANGE,0,以避免在实际没有任何更改时更新行