【问题标题】:Collections are going into loop收藏品进入循环
【发布时间】: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结果……
  • 我对@9​​87654322@ 很感兴趣。假设 previous_delinquencies 是 42,current_delinquencies 是 40。计算结果为 substr('2',2),即为空。这真的是业务逻辑吗?
  • 另请注意,bulk collect 会在每次循环迭代时替换集合的内容,因此在第一个循环结束时,它仅包含上次提取的结果。

标签: sql oracle performance


【解决方案1】:

直接更新有什么问题?

update temp_loan
set ACCOUNT_STATUS = 'STAB' 
WHERE SUBSTR((PREVIOUS_DELINQUENCIES - CURRENT_DELINQUENCIES),2) >= 31

这可能不是您想要的答案,特别是如果(根据我的评论)您在问题中发布的逻辑不代表您实际实施的逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2018-09-08
    • 1970-01-01
    • 2018-12-17
    相关资源
    最近更新 更多