Можно ли ПРОДОЛЖИТЬ цикл из исключения? - PullRequest
18 голосов
/ 05 мая 2011

У меня извлечение выполняется внутри цикла.Если эта выборка не удалась (нет данных), я бы хотел CONTINUE цикл до следующей записи из EXCEPTION.

Возможно ли это?

Я получаю ORA-06550 & PLS-00201 identifer CONTINUE must be declared

DECLARE
   v_attr char(88);
CURSOR  SELECT_USERS IS
SELECT id FROM USER_TABLE
WHERE USERTYPE = 'X';
BEGIN
    FOR user_rec IN SELECT_USERS LOOP    
        BEGIN
            SELECT attr INTO v_attr 
            FROM ATTRIBUTE_TABLE
            WHERE user_id = user_rec.id;            
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               -- user does not have attribute, continue loop to next record.
               CONTINUE;
         END;         
    END LOOP;
END;

Ответы [ 5 ]

14 голосов
/ 06 мая 2011

Оператор CONTINUE - это новая функция в 11g.

Вот связанный вопрос: Ключевое слово «ПРОДОЛЖИТЬ» в Oracle 10g PL / SQL

10 голосов
/ 06 мая 2011

В конструкции, которую вы предоставили, вам не нужно ПРОДОЛЖИТЬ.После обработки исключения выполняется оператор после END, при условии, что ваш блок EXCEPTION не завершает процедуру.Другими словами, он будет продолжен до следующей итерации цикла user_rec.

Вам также нужно ВЫБРАТЬ INTO переменную внутри вашего блока BEGIN:

SELECT attr INTO v_attr FROM attribute_table...

Очевидно, вы должны объявить v_attrа также ...

6 голосов
/ 06 мая 2011

Как насчет выражения ole goto (я знаю, я знаю, но здесь все работает отлично;)

DECLARE
   v_attr char(88);
CURSOR  SELECT_USERS IS
SELECT id FROM USER_TABLE
WHERE USERTYPE = 'X';
BEGIN
    FOR user_rec IN SELECT_USERS LOOP    
        BEGIN
            SELECT attr INTO v_attr 
            FROM ATTRIBUTE_TABLE
            WHERE user_id = user_rec.id;            
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               -- user does not have attribute, continue loop to next record.
               goto end_loop;
         END;

        <<end_loop>>
        null;         
    END LOOP;
END;

Просто поместите end_loop в самый конец цикла, конечно. Нуль может быть заменен коммитом, может быть, или счетчиком, может быть, до вас.

0 голосов
/ 22 марта 2017

Обратите внимание, что вы можете использовать WHEN exception THEN NULL так же, как вы используете WHEN exception THEN continue.Пример:

    DECLARE
        extension_already_exists  EXCEPTION;
        PRAGMA EXCEPTION_INIT(extension_already_exists, -20007);
        l_hidden_col_name  varchar2(32);
    BEGIN
        FOR t IN (  SELECT table_name, cast(extension as varchar2(200)) ext
                    FROM all_stat_extensions
                    WHERE owner='{{ prev_schema }}'
                      and droppable='YES'
                    ORDER BY 1
                 )
        LOOP
            BEGIN
                l_hidden_col_name := dbms_stats.create_extended_stats('{{ schema }}', t.table_name, t.ext);
            EXCEPTION
                WHEN extension_already_exists THEN NULL;   -- ignore exception and go to next loop iteration
            END;
        END LOOP;
    END;
0 голосов
/ 03 февраля 2017

Для этого примера вы действительно должны просто использовать внешнее соединение.

declare
begin
  FOR attr_rec IN ( 
    select attr 
    from USER_TABLE u 
    left outer join attribute_table a 
    on ( u.USERTYPE = 'X' and a.user_id = u.id ) 
  ) LOOP
    <process records> 
    <if primary key of attribute_table is null 
     then the attribute does not exist for this user.>
  END LOOP;
END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...