Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
kapelan
Member

Откуда: хутор БольшойБугор
Сообщений: 722
drop table t1;
drop table t2;

CREATE table t1 (n number , c varchar2(22));
create table t2 as select * from t1;

insert into t1
values (2,'uiui');

insert into t1
values (3,'dsdsd') ;

insert into t1
values (4,'444') ;

commit;


declare 

      CURSOR v_cr IS
        SELECT n
        FROM   t1
      FOR UPDATE;
      
begin

 FOR v_f IN v_cr LOOP
      UPDATE t1
      SET    c = 'nnn'
      WHERE CURRENT OF v_cr;
      COMMIT;
    END LOOP;
end;    


declare
*
ERROR at line 1:
ORA-01002: fetch out of sequence
ORA-06512: at line 10


то ест внутри LOOP не могет быть commit !

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE    10.2.0.3.0      Production
TNS for Solaris: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
10 сен 07, 23:22    [4646248]     Ответить | Цитировать Сообщить модератору
 Re: новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
Владимир Бегун
Member

Откуда: Redwood Shores, CA USA
Сообщений: 1707
oerr ora 1002
01002, 00000, "fetch out of sequence"
// *Cause: This error means that a fetch has been attempted from a cursor
// which is no longer valid. Note that a PL/SQL cursor loop
// implicitly does fetches, and thus may also cause this error.
// There are a number of possible causes for this error, including:
// 1) Fetching from a cursor after the last row has been retrieved
// and the ORA-1403 error returned.
// 2) If the cursor has been opened with the FOR UPDATE clause,
// fetching after a COMMIT has been issued will return the error.

// 3) Rebinding any placeholders in the SQL statement, then issuing
// a fetch before reexecuting the statement.
// *Action: 1) Do not issue a fetch statement after the last row has been
// retrieved - there are no more rows to fetch.
// 2) Do not issue a COMMIT inside a fetch loop for a cursor
// that has been opened FOR UPDATE.
// 3) Reexecute the statement after rebinding, then attempt to
// fetch again.
10 сен 07, 23:31    [4646265]     Ответить | Цитировать Сообщить модератору
 Re: новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
kapelan
Member

Откуда: хутор БольшойБугор
Сообщений: 722
Владимир Бегун
oerr ora 1002
01002, 00000, "fetch out of sequence"
// *Cause: This error means that a fetch has been attempted from a cursor
// which is no longer valid. Note that a PL/SQL cursor loop
// implicitly does fetches, and thus may also cause this error.
// There are a number of possible causes for this error, including:
// 1) Fetching from a cursor after the last row has been retrieved
// and the ORA-1403 error returned.
// 2) If the cursor has been opened with the FOR UPDATE clause,
// fetching after a COMMIT has been issued will return the error.

// 3) Rebinding any placeholders in the SQL statement, then issuing
// a fetch before reexecuting the statement.
// *Action: 1) Do not issue a fetch statement after the last row has been
// retrieved - there are no more rows to fetch.
// 2) Do not issue a COMMIT inside a fetch loop for a cursor
// that has been opened FOR UPDATE.
// 3) Reexecute the statement after rebinding, then attempt to
// fetch again.

почему тогда только в 10 об етом вспомнили?
в 9 работало прекрасно
11 сен 07, 07:31    [4646523]     Ответить | Цитировать Сообщить модератору
 Re: новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
Деев И.
Member

Откуда: отсюда
Сообщений: 783
kapelan
почему тогда только в 10 об етом вспомнили?
в 9 работало прекрасно


Это работало, если другая сессия в этот момент не успевала другие данные, выводимые курсором, проапдейтить. Иначе - та же ошибка возникала. Ужесточили требования. Вообще-то правильно - открываем SELECT FOR UPDATE и тут же COMMIT после изменения первой строки? Нелогично - мы завершаем транзакцию, и пытаемся тут же читать данные, соответствующие состоянию до ее завершения, и все это в рамках одной сессии. Мультиверсионность в рамках одной сессии без обращения к Flashback?

И коммитить каждую строчку - нехороший подход (хотя могут быть очень редкие исключения из правил), поскольку ресурсы лишние тратятся, и можете нарваться на то, что данные в REDO будут перезаписаны и возникнет snapshot too old (например, если индекс используется, данные достаточно объемные и REDO не такой большой).
11 сен 07, 10:10    [4646929]     Ответить | Цитировать Сообщить модератору
 Re: новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
Elic
Member

Откуда:
Сообщений: 29976
kapelan
почему тогда только в 10 об етом вспомнили?
в 9 работало прекрасно
Эта фича гораздо старше. Надо просто внимательно RTFM Fetching Across Commits (FAQ)

А в 9.2.0.8 просто баг, аналогичный
Bug 696531 ORA-1002 *NOT* Being returned - commit in a fetch loop with select for update (8.1.6.2),
т.е. A COMMIT In A Cursor Raises ORA-01002 After Upgrading To 8.1.7
11 сен 07, 10:59    [4647312]     Ответить | Цитировать Сообщить модератору
 Re: новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
Деев И.
Member

Откуда: отсюда
Сообщений: 783
Будем знать.
11 сен 07, 11:38    [4647763]     Ответить | Цитировать Сообщить модератору
 Re: новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
Далай-ламо
Member

Откуда: никого не Тибёт
Сообщений: 92
Деев И.
kapelan
почему тогда только в 10 об етом вспомнили?
в 9 работало прекрасно


Это работало, если другая сессия в этот момент не успевала другие данные, выводимые курсором, проапдейтить. Иначе - та же ошибка возникала. Ужесточили требования. Вообще-то правильно - открываем SELECT FOR UPDATE и тут же COMMIT после изменения первой строки? Нелогично - мы завершаем транзакцию, и пытаемся тут же читать данные, соответствующие состоянию до ее завершения, и все это в рамках одной сессии. Мультиверсионность в рамках одной сессии без обращения к Flashback?

И коммитить каждую строчку - нехороший подход (хотя могут быть очень редкие исключения из правил), поскольку ресурсы лишние тратятся, и можете нарваться на то, что данные в REDO будут перезаписаны и возникнет snapshot too old (например, если индекс используется, данные достаточно объемные и REDO не такой большой).
Видать травка была забористая :)
Будем знать :)
11 сен 07, 12:00    [4648004]     Ответить | Цитировать Сообщить модератору
 Re: новый баг или фикс старого в oracle 10g ? (cursor for update)  [new]
kapelan
Member

Откуда: хутор БольшойБугор
Сообщений: 722
Деев И.
kapelan
почему тогда только в 10 об етом вспомнили?
в 9 работало прекрасно


Это работало, если другая сессия в этот момент не успевала другие данные, выводимые курсором, проапдейтить. Иначе - та же ошибка возникала. Ужесточили требования. Вообще-то правильно - открываем SELECT FOR UPDATE и тут же COMMIT после изменения первой строки? Нелогично - мы завершаем транзакцию, и пытаемся тут же читать данные, соответствующие состоянию до ее завершения, и все это в рамках одной сессии. Мультиверсионность в рамках одной сессии без обращения к Flashback?

И коммитить каждую строчку - нехороший подход (хотя могут быть очень редкие исключения из правил), поскольку ресурсы лишние тратятся, и можете нарваться на то, что данные в REDO будут перезаписаны и возникнет snapshot too old (например, если индекс используется, данные достаточно объемные и REDO не такой большой).

Ну да не логично ...
однако удобно было .
11 сен 07, 16:47    [4650916]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить