我想选择多行并更新所有选定的行。所以这个目标我写了这个查询。但是当执行它时会抛出异常。
我在像bellow这样的制片人中写过这个问题。
PROCEDURE get_rows(
a_cursor OUT SYS_REFCURSOR,
a_id IN VARCHAR,
a_count IN NUMBER);
异常细节:
java.sql.SQLException:ORA-01002:fetch out of sequence
a_cursor
是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;
答案 0 :(得分:2)
sys_refcursor
语句中无法使用update
。您可以使用显式游标,如下所示。使用这种方式:
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;
编辑:
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 ;
答案 1 :(得分:2)
如果你没有在循环中进行任何其他处理,你可以使用MERGE
语句而不是游标:
Oracle 11g R2架构设置:
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;
查询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'
查询2 :
SELECT * FROM mytable
<强> Results 强>:
| VID | COLUMNA |
|-----|---------|
| 1 | b |
| 2 | b |
| 3 | b |
| 4 | a |
| 5 | a |
| 6 | a |