【发布时间】:2021-03-11 00:41:19
【问题描述】:
我想更新表格,但是,集合进入循环。需要更新 500 000 条记录,但这需要很多时间..如果可以做点什么..
CREATE OR REPLACE PROCEDURE PROC_ACCOUNT_STATUS AS
CURSOR C1 IS
SELECT ACCOUNTS1,
abs((PREVIOUS_DELINQUENCIES - CURRENT_DELINQUENCIES)) AS DIFF_DEL
FROM TEMP_LOAN;
TYPE COLL_ACCOUNT_STATUS IS TABLE OF C1%ROWTYPE;
COLL_STAB1 COLL_ACCOUNT_STATUS := COLL_ACCOUNT_STATUS();
COLL_STAB2 COLL_ACCOUNT_STATUS := COLL_ACCOUNT_STATUS();
BEGIN
OPEN C1;
LOOP
FETCH C1 BULK COLLECT INTO COLL_STAB2 LIMIT 500;
EXIT WHEN COLL_STAB2.COUNT = 0;
COLL_STAB1 := COLL_STAB2;
END LOOP;
CLOSE C1;
FOR I IN 1..COLL_STAB1.COUNT
LOOP
IF(COLL_STAB1(I).DIFF_DEL>=30) AND(COLL_STAB1(I).DIFF_DEL>=31) THEN
COLL_STAB1.EXTEND();
COLL_STAB1(COLL_STAB1.COUNT):=COLL_STAB1(I);
END IF;
END LOOP;
FORALL I IN 1..COLL_STAB1.COUNT
UPDATE TEMP_LOAN
SET ACCOUNT_STATUS = 'STAB'
WHERE ACCOUNTS1 = COLL_STAB1(I).ACCOUNTS1;
COLL_STAB1.DELETE;
COLL_STAB2.DELETE;
COMMIT;
END;
【问题讨论】:
-
这是您的实际代码(而不是您发明并在这里发布的一些经过编辑的代码)?因为它似乎没有多大意义。似乎有很多不必要的处理,这会占用时间。也许您可以解释您尝试实施的业务规则,我们可以提供更好的方法来实现这一点。
-
500,000 并没有那么多,你应该能够在一分钟内完成那么多行查找。也就是说,您将更新此表中的每一行,那么为什么还要为循环更新而烦恼呢?如果可以的话,APC 的答案将是首选路线。如果您必须执行程序逻辑并按行进行更新,那么您可能只是缺少该过滤列上的关键索引。
-
@AndrewSayer 更新 500K结果……
-
我对@987654322@ 很感兴趣。假设
previous_delinquencies是 42,current_delinquencies是 40。计算结果为substr('2',2),即为空。这真的是业务逻辑吗? -
另请注意,
bulk collect会在每次循环迭代时替换集合的内容,因此在第一个循环结束时,它仅包含上次提取的结果。
标签: sql oracle performance