2013-09-26 3 views
0

Мои навыки PL/SQL очень ограничены, поэтому я приношу свои извинения, если это не проблема. В принципе, у меня есть цикл, который повторяется через клоб. Цикл дал мне проблемы в прошлом (бесконечный цикл), когда значение clob равно null. Я попытался выполнить некоторые проверки кода для этого цикла, однако мои попытки предотвратить бесконечный цикл не удались.PL/SQL Бесконечная петля

Вот соответствующие фрагменты кода:

 v_offset  NUMBER DEFAULT 1; 
     v_response  CLOB; 

     SELECT VALUE 
     INTO v_response 
     FROM json_cache 
     WHERE json_key = 'EMPLOYEES'; 

     --infinite loop occurs when v_response = '' 
     LOOP 
      EXIT WHEN v_offset > DBMS_LOB.getlength (v_response) 
       or DBMS_LOB.getlength (v_response) = 0 
       or v_offset = 400000; 
      HTP.prn (DBMS_LOB.SUBSTR (v_response, 20000, v_offset)); 
      v_offset := v_offset + 20000; 
     END LOOP; 

не должны дополнительные условия в EXIT WHEN заявлении предотвратить зацикливание возникновения? Как завершить или предотвратить этот цикл, когда v_response пуст? Я хотел бы избежать обертывания этого цикла в выражении if и предпочел бы охрану в цикле.

+0

Я немного ржавый на моем PLSQL, но если установить значение по умолчанию от смещения до 1, не будет рассчитывать 1, 20001, 40001 и т.д. в цикле? – sekky

+0

@sekky Да, но не рассмотрит ли это два других условия? 'DBMS_LOB.getlength (v_response) = 0 или v_offset = 400000' и ​​в конечном итоге остановить цикл? –

+0

Тогда v_offset = 400000 не удовлетворит. Вы можете использовать либо v_offset = 400001, либо v_offset> 400000 – dcp1986

ответ

2

Вы всегда можете проверить на нулевое значение:

loop 
    exit when v_offset > dbms_lob.getlength (v_response) 
     or dbms_lob.getlength (v_response) = 0 
     or v_offset = 400000 
     or dbms_lob.getlength (v_response) is null; 
    v_offset := v_offset + 20000; 
end loop; 
+0

И инициализировать v_offset до 0 вместо 1 – furman87

0

Вы можете добавить дополнительный контроль в конце, как это;

DECLARE 
    v_offset  NUMBER DEFAULT 1; 
    v_response  CLOB; 
BEGIN 
    SELECT VALUE 
    INTO v_response 
    FROM json_cache 
    WHERE json_key = 'EMPLOYEES'; 

    --infinite loop occurs when v_response = '' 
    LOOP 
     EXIT WHEN v_offset > DBMS_LOB.getlength (v_response) 
      or DBMS_LOB.getlength (v_response) = 0 
      or v_offset = 400000; 
     HTP.prn (DBMS_LOB.SUBSTR (v_response, 20000, v_offset)); 
     v_offset := v_offset + 20000; 

     if v_response is null then 
     exit; 
     end if; 
    END LOOP; 
END; 
Смежные вопросы