我需要在 Informix 中更新大量行,但是当运行更新语句时,它会锁定整个更新过程中使用该表的每个人。
sql语句:
UPDATE informix.article SET article_qta_ord=NVL((select SUM(CASE WHEN(qta_ordered NVL(qta_loaded, 0))>0 THEN (qta_ordered-NVL(qta_loaded, 0)) ELSE 0 END) from informix.order_table where order_article_code = article_code and whsId = '5'), 0)
是否可以使用存储过程进行大量更新,并定期提交或使用 dbaccess 内的 rowid 选择更新,以避免在整个更新过程中锁定每个人?
将
SELECT
FOR UPDATE
与 ROWID
一起使用可以帮助管理并发。
CREATE PROCEDURE update_article_qta_ord()
DEFINE commit_interval INT;
DEFINE row_count INT;
-- Set the number of rows to process in each batch
LET commit_interval = 100;
-- Declare cursor with SELECT FOR UPDATE
DECLARE article_cursor CURSOR FOR
SELECT article_code, ROWID
FROM informix.article
WHERE article_qta_ord IS NULL; -- Add any additional conditions as needed
OPEN article_cursor;
-- Loop through the cursor
FETCH article_cursor INTO article_code, article_rowid;
WHILE (SQLCODE = 0) DO
BEGIN
-- Your update logic here
UPDATE informix.article
SET article_qta_ord = NVL(
(SELECT SUM(CASE WHEN (qta_ordered NVL(qta_loaded, 0)) > 0 THEN (qta_ordered - NVL(qta_loaded, 0)) ELSE 0 END)
FROM informix.order_table
WHERE order_article_code = article_code AND whsId = '5'), 0)
WHERE CURRENT OF article_cursor;
-- Commit periodically
LET row_count = row_count + 1;
IF row_count % commit_interval = 0 THEN
COMMIT;
END IF;
-- Fetch the next row
FETCH article_cursor INTO article_code, article_rowid;
EXCEPTION
WHEN OTHERS THEN
-- Handle exceptions as needed
ROLLBACK;
CLOSE article_cursor;
RETURN;
END;
END WHILE;
-- Commit any remaining changes
COMMIT;
CLOSE article_cursor;
END PROCEDURE;
此存储过程使用带有
SELECT FOR UPDATE
的游标在处理过程中锁定每一行。定期使用 COMMIT
语句来释放锁并减少争用。调整 commit_interval
变量来控制提交发生的频率。