引言:爲了紀念將要離去的DBA,記下這個關於ORA-01002的日誌。
ORA-01002 fetch out of sequence
Cause: In a host language program, a FETCH call was issued out of sequence.
A successful parse-and-execute call must be issued before a fetch. This can
occur if an attempt was made to FETCH from an active set after all records have
been fetched. This may be caused by fetching from a SELECT FOR UPDATE
cursor after a commit. A PL/SQL cursor loop implicitly does fetches and may
also cause this error.
Action: Parse and execute a SQL statement before attempting to fetch the data.
--------------------
意思就是說,如果一個遊標你COMMIT了,但又試圖去FETCH,那麼就會出現這個錯誤,因爲COMMIT的之後,系統認爲需要FETCH的已經FETCH了,典型的是FOR UPDATE,但隱式的遊標FETCH也可能導致這個問題。
舉例就更清楚了。
例子1:PL/SQL DEVELOPER 7.X
第一步:提取數據
第二步驟:修改第二行中的KHRQ爲3,並點擊COMMIT按鈕(綠色那個)
點了之後變爲灰色。
第三步: 再次點擊FETCH圖標(倒數第二個綠色按鈕),結果如下:
結論1:COMMIT之後,認爲當前的需要提取的數據都提取了,還想再FETCH,則會使得指針指向錯誤的地方,結果異常出現。
例子二:PL/SQL BLOCK 代碼
declare
r sys_refcursor;
x test%rowtype;
begin
open r for select * from test for update;
fetch r into x;
commit;
close r;
end;
運行之後,ok。
換一段代碼:
declare
r sys_refcursor;
x test%rowtype;
begin
open r for select * from test for update;
fetch r into x;
commit;
fetch r into x;
close r;
end;
運行,則提示如下:
這下明白了吧?
結論:簡而言之,不要在commit一個for update遊標之後再fetch,