2017-02-17 11 views
2

Сегодня я столкнулся с «FETCH OUT OF SEQUENCE» ORA-01002. Я провел много исследований, и я понял, что это довольно часто, когда мы это делаем.Извлечение из последовательности <ora-01002> Откат

  1. Попытайтесь получить, когда мы уже закрыли курсор.
  2. Для обновления и фиксации.

Мое требование состоит в том, чтобы зафиксировать каждые 500 записей, если они были успешно обработаны, и в случае каких-либо проблем отката извлеченных 500 записей.

Я не сделал ни одного из них. Я также обнаружил, что выборка из последовательности произошла из-за ROLLBACK;

Я также сузился до того, когда это происходит на самом деле. Это происходит только тогда, когда выполняется откат для первого набора записей.

loop 
    Fetch c1 bulk collect into type1 limit 500; 
    exit when type1.count=0; 
    forall in i..type1.count save exceptions 
    insert into the table. 
    do something..... 
    the computation goes on; 
    Commit; 
    exception when others then 
    for i in 1..sql%bulk_exceptions loop 
    Do somthing... 
    end loop; 
    rollback; => Fetch out of seq happens here... 
    end loop; 

Извлечение из последовательности происходит только в том случае, если первые 500 записей не удались и когда я выдаю команду отката. Он не дает ora-01002, когда первые 500 записей зачисляются, а для следующих 500 записанных записей отменяется.

Любые причины, по которым он действует таким образом. Пожалуйста, предложите, если есть способ избежать ошибки ora-01002.

Извините, не удалось опубликовать кодировки здесь из-за политики компании. Но приведенный выше псевдокод - это то, как кодируется.

Дополнительная информация-> Если я делаю программу таким образом, то я не получаю ошибку «ORA-01002».

loop 
Fetch c1 bulk collect into type1 limit 500; 
exit when type1.count=0; 
COMMIT; => IF I ADD COMMIT HERE ORA-01002 doesnt appear. 
forall in i..type1.count save exceptions 
insert into the table. 
do something..... 
the computation goes on; 
Commit; 
exception when others then 
for i in 1..sql%bulk_exceptions loop 
Do somthing... 
end loop; 
rollback; => Fetch out of seq happens here... 

конец петли;

ответ

2

Эта ошибка означает, что выборка была предпринята с помощью курсора, который больше не является valid. Обратите внимание, что курсор курсора PL/SQL неявно выполняет выборку и, следовательно, также может вызывать эту ошибку. Существует ряд возможных причин этой ошибки, в том числе:

1) Извлечение из курсора после того, как последняя строка была восстановлена, и возвращается ошибка ORA-1403.

2) Если курсор был открыт с предложением FOR UPDATE, выборка после выпуска COMMIT вернет ошибку.

3) Перематывание любых заполнителей в инструкции SQL, а затем выдача выборки перед повторным выполнением оператора.

Действие:

1) Не выдавать выборки заявления после последней строки было восстановлено - там нет строк больше.

2) Не выпускайте COMMIT внутри цикла выборки для курсора, который был открыт для ОБНОВЛЕНИЯ.

3) Повторите выполнение инструкции после повторного связывания, затем попытайтесь извлечь ее снова.

ORA-01002 может иметь несколько причин, в том числе:

• петля, PL/SQL делает выборку без уведомления

• Попытка извлечения из курсора, что больше не является действительным (выборка из строки, которая имеет был получен).

• Получение после того, как COMMIT уже выпущен, и курсор открывается с предложением FOR UPDATE.

• Выдача выборки перед повторным выполнением SQL после переупорядочения заполнителей.

Возможно, вы захотите попробовать использовать атрибуты курсора для уклонения ORA-01002 в будущем.

Для устранения тока ORA-01002, есть три действия, которые можно выполнить:

1.After последнюю запись получили, не выдавать выборки

2.Inside выборка петли на ВЫБРАТЬ FOR UPDATE, не используйте ПОРУЧАТЬ

3.Try выборки снова после повторного выполнения оператора (после подмены)

источника: ora-01002

+0

Xing, как я сказал, «ошибка возникает только в том случае, если я откатываю первый набор записей коллективного сбора». Почему это происходит? –

+0

@ Premakumari. Наверное, мне немного поздно объяснять. J. Chomel объяснил это очень хорошо. Спасибо – XING

+0

Xing Ваш комментарий также ценится мною. Благодарим вас за ваши идеи и идеи. Я изучаю plsql, поэтому вам нужна большая помощь от таких людей, как вы, даже если вы объясните позже :). Спасибо anyways :) –

2

Когда вы обрабатываете свои записи таким образом, вы не должны иметь commit/rollback, как это, в середине обработки. Rollback недействительный текущий курсор. Вы должны зафиксировать после 500 записей в любом случае и обрабатывать исключения.

Oracle не может вспомнить, где его курсор должен быть после откат.

Как и в заявлении 7 из this example, вы должны обращаться с унитарные исключениями FORALL в случае

--- declare exception 
failure_in_forall EXCEPTION; 
PRAGMA EXCEPTION_INIT (failure_in_forall, -24381); 

... 
-- handle it 
EXCEPTION 
     WHEN failure_in_forall 
    ... 

Тогда ваши хорошие записи будут обработаны и совершенные, и плохие, которые будут рассмотрены и обработаны позже

+0

@J Chomel Спасибо большое. Я понимаю, что курсор становится недействительным из-за отката. Но у меня все еще есть сомнения. Откат недействителен, только если я использую для обновления. Исправьте меня, если я ошибаюсь. Спасибо –

+0

Кроме того, когда я COMMIT перед тем, как собирать объемный сбор в тип, а затем дать откат, проблема исчезнет. Почему это так? –

+0

Также я не могу использовать PRAGMA EXCEPTION_INIT для нормального цикла, исправьте меня, если я ошибаюсь. –