DB2 UDB v11.x.
是否可以在使用CASE的UPDATE查询中使用FETCH FIRST? 我有点明白为什么它不工作,但想知道是否有一种方法,例如。
db2 "UPDATE mytable SET cstate = CASE WHEN cstate = 801 THEN cstate = 1 AND rstate = 1 WHEN cstate = 804 THEN cstate = 4 AND rstate = 4 END FETCH FIRST 20000 ROWS ONLY"
这样做的结果是一次只能修改一条记录。
我试过了。
db2 "UPDATE mytable SET cstate = CASE WHEN cstate = (SELECT cstate FROM mytable WHERE cstate = 801 FETCH FIRST 20000 ROWS ONLY) THEN cstate = 1 AND rstate = 1 WHEN cstate = (SELECT cstate FROM mytable WHERE cstate = 804 FETCH FIRST 20000 ROWS ONLY) THEN cstate = 4 AND rstate = 4 END"
这得到的结果是:
SQL0811N The result of a scalar fullselect, SELECT INTO statement, or VALUES
INTO statement is more than one row
有什么方法可以做到这一点?希望不要把它拆分开来,在表中重申两次(或者一次只能做一次更新)。
这将是最简单的方法
UPDATE
( SELECT * FROM
( SELECT
cstate
, rstate
, CASE WHEN cstate = 801 THEN 1 WHEN cstate = 804 THEN 4 ELSE cstate END new_cstate
, CASE WHEN cstate = 801 THEN 1 WHEN cstate = 804 THEN 4 ELSE rstate END new_rstate
FROM
mytable
)
WHERE
cstate IS DISTINCT FROM new_cstate
OR rstate IS DISTINCT FROM new_rstate
FETCH FIRST 20000 ROWS ONLY
)
SET cstate = new_cstate
, rstate = new_rstate
只需继续运行,直到没有更新记录为止。
在处理子查询时,请使用IN子句,你可能在另一个表中有多个值。
"UPDATE mytable SET cstate = CASE WHEN cstate in (SELECT cstate FROM mytable WHERE cstate = 801 FETCH FIRST 20000 ROWS ONLY) THEN cstate = 1 AND rstate = 1 WHEN cstate in (SELECT cstate FROM mytable WHERE cstate = 804 FETCH FIRST 20000 ROWS ONLY) THEN cstate = 4 AND rstate = 4 END"
你可以试试 positioned update
与提交后N个这样的更新。
--#SET TERMINATOR @
BEGIN
DECLARE V_BATCH_COUNT INT DEFAULT 0;
FOR V AS C1 CURSOR WITH HOLD FOR
SELECT 1 DUMMY FROM mytable FOR UPDATE OF cstate, rstate
DO
UPDATE mytable
SET
cstate = ...
, rstate = ...
WHERE CURRENT OF C1;
SET V_BATCH_COUNT = V_BATCH_COUNT + 1;
IF V_BATCH_COUNT = 20000 THEN
COMMIT;
SET V_BATCH_COUNT = 0;
END IF;
END FOR;
IF V_BATCH_COUNT <> 0 THEN
COMMIT;
END IF;
END
@
它的工作速度很慢,但可以帮助你避免长时间的过度锁定:)