我有以下查询
select distinct name from table1
intersect
select distinct name from table2;
我将结果集加载到PL / SQL过程中的游标中,如下所示:
cursor c1 is (select distinct name from table1
intersect
select distinct name from table2);
由于某种原因,结果集中的最后一个值在游标中重复。单独运行查询时不会发生这种情况。任何想法为什么会发生这种情况?
循环代码:
var table.col%type;
BEGIN
OPEN c1;
LOOP
BEGIN
exit when c1%NOTFOUND;
FETCH c1 into var;
INSERT INTO table values (col1, var);
commit;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
CONTINUE;
END;
END LOOP;
END;
答案 0 :(得分:2)
EXIT WHEN ..
子句应该在FETCH
之后。
假设您的光标有10条记录要返回。在第一次提取被触发之前,%NOTFOUND
被评估为NULL
,处理将移至下一个语句,在您的情况下为FETCH
。现在,如果我们快进到第10次迭代,FETCH将获得第10条记录,并将相同内容插入到目标表中。循环将向前移动,并且因为你的EXIT WHEN %NOTFOUND
在获取之前,它仍然具有上次迭代的值,并且它让控制向前移动,并且在那里,fetch将无法获得任何记录,但是代码将以任何方式插入它在第10次迭代中检索的最后一行。现在在下一个循环中,c1%NOTFOUND
将被评估为TRUE
,循环将终止
var table.col%type;
BEGIN
OPEN c1;
LOOP
BEGIN
FETCH c1 into var;
exit when c1%NOTFOUND;
INSERT INTO table values (col1, var);
commit;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
CONTINUE;
END;
END LOOP;
END;
答案 1 :(得分:-2)
这是您使用显式游标看到的典型问题。
您的首选应该是单个SQL语句,仅此而已。
如果必须使用游标,则应尽可能使用隐式游标。