文檔中的解釋:It returns TRUE
if an INSERT
, UPDATE
, or DELETE
statement affected no rows, or a SELECT
INTO
statement returned no rows. Otherwise, it returns FALSE
.
這個解釋更加精妙:%NOTFOUND
is the logical opposite of %FOUND
. %NOTFOUND
yields FALSE
if the last fetch returned a row, or TRUE
if the last fetch failed to return a row
錯誤的例子:
tableA
id name
1 a
2 b
declare
cursor v_cur is select name from tableA;
n varchar2(10);
begin
open v_cur;
loop
exit when v_cur%notfound;
fetch v_cur into n;
dbms_output.put_line(n);
close v_cur;
end loop;
end;
執行上面的語句,結果為:
a
b
b
發現最后一條記錄被打印了兩次。原因是%notfound是判斷最后一次fetch的結果,把bfetch到變量n中之后再執行exit when %notfound判斷得到的是false的記過,也就是說是有返回行的,所以判斷通過,再此執行了打印語句。
發現了另一個疑問:
把a,b都fetch之后按理說游標已經空了,那么第三次應該是fetch的空值,為什么打印出來的還是b呢??
因為fetch..into語句末尾不會修改into變量后面的值。就像select..into如果沒有數據會報異常,但是不會把into后面的變量置為空
再寫一段代碼
declare
cursor v_cur is select name from tableA where name = 'c';
n varchar2(10);
begin
open v_cur;
loop
exit when v_cur%notfound;
n:='hehe'
fetch v_cur into n;
dbms_output.put_line(n);
close v_cur;
end loop;
end;
執行代碼的結果:
hehe
疑問:游標是空游標,也就是說游標在打開的時候就沒有指向任何的值。但為什么
exit when v_cur%notfound;這條語句還通過了呢??
oracle文檔的解釋:
Before the first fetch, %NOTFOUND
returns NULL
. If FETCH
never executes successfully, the loop is never exited, because the EXIT
WHEN
statement executes only if its WHEN
condition is true. To be safe, you might want to use the following EXIT
statement instead:
EXIT WHEN c1%NOTFOUND OR c1%NOTFOUND IS NULL;
也就是說v_cur%notfound有三種狀態,true,false,null。所以以后為了安全期間可以加上是否為空的判斷