在UPDATE

时间:2018-10-16 15:11:54

标签: sql db2

我有一条UPDATE语句,该语句将使用@CHANGE(正整数或负整数)并更新该类型项目的CURRENT_INVENTORY

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;

我想知道运行此更新前后的CURRENT_INVENTORY是什么。是否可以选择OLD TABLE的{​​{1}} FINAL TABLE值?

我要显示一条消息,内容为“ {位置}库存从{旧}更改为{新}”。我可以使用单独的SELECT获取旧值/当前值,在代码中进行数学运算,然后更新表上的行。我认为这很容易受到竞争条件的影响(因为第一个SELECT不会锁定行),所以我试图在单个查询中进行。

我认为我不能同时选择OLD和FINAL,所以我认为最好的解决方案是:

  1. CURRENT_INVENTORY中选择值,并复制CASE语句中的逻辑以得出新值
  2. OLD TABLE中选择一个值,然后选择新值(由于UPDATE锁定了该行,因此在同一事务中)

是否有更好/正确的方法来实现这一目标?

2 个答案:

答案 0 :(得分:3)

您可以为此使用“从更新中选择”(SQL手册)。 示例:

SELECT EMPNO, SALARY, BONUS , OLD_SALARY , OLD_BONUS
    FROM FINAL TABLE
        (UPDATE EMP  INCLUDE  ( OLD_SALARY DECIMAL(9,2)
                              , OLD_BONUS DECIMAL(9,2))
        SET SALARY     = SALARY+1000
        ,   BONUS      = 0
        ,   OLD_SALARY = SALARY
        ,   OLD_BONUS  = BONUS
        WHERE SALARY > 28000);

答案 1 :(得分:1)

更新内联视图而不是表:

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
);