PL / SQL控制结构 - LOOP

时间:2016-03-16 14:12:59

标签: sql oracle plsql

我有大约94,000条需要删除的记录,但我被告知不要一次删除所有记录,因为它会因删除触发器而降低性能。实现这一目标的最佳解决方案是什么?在提交1000之后我想到了一个额外的循环,但不太确定如何实现或知道这是否会进一步降低性能。

DECLARE  
  CURSOR CLEAN IS
  SELECT EMP_ID, ACCT_ID FROM RECORDS_TO_DELETE F; --Table contains the records that needs to be deleted.
  COUNTER INTEGER := 0;

BEGIN
  FOR F IN CLEAN LOOP
    COUNTER := COUNTER + 1;
    DELETE FROM EMPLOYEES
    WHERE EMP_ID = F.EMP_ID AND ACCT_ID = F.ACCT_ID;         

    IF MOD(COUNTER, 1000) = 0 THEN     
      COMMIT;
    END IF;
  END LOOP;
  COMMIT;
END;

3 个答案:

答案 0 :(得分:1)

您需要在oracle中阅读一些关于BULK COLLECT语句的内容。这通常被认为是处理大型表的正确方法。

示例:

    LOOP
        FETCH c_delete BULK COLLECT INTO t_delete LIMIT l_delete_buffer;

        FORALL i IN 1..t_delete.COUNT
            DELETE ps_al_chk_memo
             WHERE ROWID = t_delete (i);

            COMMIT;
        EXIT WHEN c_delete%NOTFOUND;
        COMMIT;
    END LOOP;
    CLOSE c_delete;

答案 1 :(得分:1)

你可以在一个声明中做到这一点,这应该是任何类型的最快方式:

      try {
      selector.select();

      Iterator<SelectionKey> it = selector.selectedKeys().iterator();

      while (it.hasNext()) {
        SelectionKey key = it.next();
        it.remove();
        if (key.isValid()) {
          if (key.isReadable()) {
            doRead(key);
          }
        }
      }

    } catch (IOException e) {
      LOG.warn("Run into IOExpection in " + name, e);
    }

答案 2 :(得分:0)

因为我可以看到记录的数量不是那么多,所以仍然可以使用SQL而不是PLSQL。尽可能尝试SQL。我认为它不应该对性能产生太大影响。

DELETE FROM EMPLOYEES
WHERE EXISTS
(SELECT 1 FROM RECORDS_TO_DELETE F
WHERE EMP_ID = F.EMP_ID 
AND ACCT_ID= F.ACCT_ID);   

希望这有帮助。