oracle数据库%notfound的理解

文档中的解释:

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的结果,把b fetch到变量n中之后再执行exit when %notfound判断得到的是false的记过,也就是说是有返回行的,所以判断通过,再此执行了打印语句。
发现了另一个疑问:
a,bfetch之后按理说游标已经空了,那么第三次应该是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。所以以后为了安全期间可以加上是否为空的判断


oracle数据库中sql%notfound的用法详解

SQL%NOTFOUND 是一个布尔值。与最近的sql语句(update,insert,delete,select)发生交互,当最近的一条sql语句没有涉及任何行的时候,则返回true。否则返回false。这样的语句在实际应用中,是非常有用的。例如要update一行数据时,如果没有找到,就可以作相应操作。如:

begin
 update table_name set salary = 10000 where emp_id = 10;
 if sql%notfound then
  insert into table_name (id,name,salary)values("","","") ;
 end if;
end;

update emp_id10的这行记录,如果update影响条数为0,则插入一条数据。

SQL%FOUND 的用法与sql%notfound用法相反,也是与最近的sql语句发生交互,如果影响行数大于0条,则为true,否则为false

SQL%ROWCOUNTdml语句执行前是null,执行后,对于select into语句,执行成功则值为1,不成功则值为0


cursor%NOTFOUND
表示这个游标没有查到数据

–%FOUND – SQL语句影响了一行或多行时为 TRUE

–%NOTFOUND – SQL语句没有影响任何行时为TRUE

–%ROWCOUNT – SQL语句影响的行数

–%ISOPEN - 游标是否打开,始终为FALSE

阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页