可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to select multiple rows and also update all selected rows. so this goal i wrote this query. but when execute it throw exception.
I wrote this query in a producer like bellow.
PROCEDURE get_rows( a_cursor OUT SYS_REFCURSOR, a_id IN VARCHAR, a_count IN NUMBER);
exception detail:
java.sql.SQLException: ORA-01002: fetch out of sequence
a_cursor
is SYS_REFCURSOR
OPEN a_cursor FOR SELECT mytable.VID FROM mytable WHERE ROWNUM <= COUNT FOR UPDATE; loop FETCH a_cursor INTO a_id; if a_cursor %notfound then cnumber := 9999; else UPDATE mytable SET ... WHERE VID = a_vid; COMMIT; end if; end loop;
回答1:
A sys_refcursor
cannot be used in update
statement. You can use an explicit cursor as shown below. Use this way:
DECLARE cursor a_cursor is SELECT mytable.VID FROM mytable WHERE ROWNUM <= COUNT FOR UPDATE; a_id number; begin OPEN a_cursor; loop FETCH a_cursor INTO a_id; exit when a_cursor%notfound; UPDATE mytable SET ... WHERE VID = a_vid; end loop; COMMIT; close a_cursor; end;
Edit:
create or replace PROCEDURE get_rows( a_cursor OUT SYS_REFCURSOR, a_id IN VARCHAR, a_count IN NUMBER) IS cursor a_cur is SELECT mytable.VID FROM mytable WHERE ROWNUM <= a_COUNT ; a_id NUMBER; cnumber number; BEGIN OPEN a_cur; LOOP FETCH a_cur INTO a_id; IF a_cur%notfound THEN cnumber := 9999; End if; exit when a_cursor%notfound; UPDATE mytable SET ... WHERE VID = a_vid; END loop; COMMIT; CLOSE a_cur; Open a_cursor for select * from mytable; end ;
回答2:
If you are not doing any other processing in the loop, you can use a MERGE
statement instead of a cursor:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE mytable ( vid, columna ) AS SELECT 1, 'a' FROM DUAL UNION ALL SELECT 2, 'a' FROM DUAL UNION ALL SELECT 3, 'a' FROM DUAL UNION ALL SELECT 4, 'a' FROM DUAL UNION ALL SELECT 5, 'a' FROM DUAL UNION ALL SELECT 6, 'a' FROM DUAL;
Query 1:
MERGE INTO mytable dst USING ( SELECT VID /* or ROWID AS rid */ FROM mytable WHERE ROWNUM <= 3 ) src ON ( src.VID = dst.VID /* or src.RID = dst.ROWID */ ) WHEN MATCHED THEN UPDATE SET columna = 'b'
Query 2:
SELECT * FROM mytable
Results:
| VID | COLUMNA | |-----|---------| | 1 | b | | 2 | b | | 3 | b | | 4 | a | | 5 | a | | 6 | a |