现在的位置: 首页 > 综合 > 正文

理解游标(3)隐式游标的使用

2013年08月04日 ⁄ 综合 ⁄ 共 1690字 ⁄ 字号 评论关闭

      当我们执行DML或Select into时,PL/SQL引擎会为我们声明一个隐式游标并管理这个游标
      之所以谓之“隐式”是因为和游标相关的工作数据库已经替我们自动做好了
      我们使用隐式游标,实际就是期待返回一行,这里有一个原则:
      对于单行记录查询,我们应该总是将它封装到一个位于包里的函数,把这个查询隐藏在一个函数接口后面,然后用return语句返回数据
      隐式游标是具有下面这些特殊性质的select语句:
        ① 这个select语句出现在代码块中的执行单元,而显示游标是在声明单元定义
        ② 查询带有into语句(批量处理则是bulk collect into)
        ③ 我们不必打开、提取或者关闭SELECT语句,所有这些操作都是由数据库替我们完成
        隐式查询的通常结构:
        SELECT column_list [BULK COLLECT] INTO PL/SQL variable_list
      虽然数据库自动替我们执行打开、提取、关闭等操作,但我们还是可以通过隐式游标的属性值获得最近执行的SQL语句的信息


      ㈠ 隐式游标的例子
        
         隐式游标的常见用法是根据主键进行查找
         下面这个例子使用查询把一行信息取到一个记录中
         表:customers
         主键:cust_id

     DECLARE
       l_customer customers%rowtype;
     BEGIN
       SELECT * INTO l_customer FROM customers WHERE cust_id=1;
     END;

         对于这种单行查询,根据上面的原则,我们通常会将它们隐藏在函数接口后面
         如果我们要获取的信息多于一行,我们必须为查询或者使用显示游标,或者使用BULK COLLECT INTO语句

 

      ㈡ 隐式游标的异常处理
        
         两种可能异常:
         ① NO_DATA_FOUND:找不到匹配行
         ② TOO_MANY_ROWS:返回结果超过一行
         作为一个规则,我们在编写隐式查询时总是要带上NO_DATA_FOUND和TOO_MANY_ROWS异常处理句柄

     FUNCTION book_title (isbn_in IN books.isbn%TYPE)
     RETURN books.title%TYPE
     IS 
     return_value books.title%TYPE;
     BEGIN
       SELECT title INTO return_value FROM books WHERE isbn=isbn_in;
     RETURN return_value;
     EXCEPTION
       WHEN  NO_DATA_FOUND
       THEN 
         RETURN NULL;
       WHEN  TOO_MANY_ROWS 
       THEN
         errpkg.record_and_stop('data error: '||isbn_in);
         RAISE;
     END;

      ㈢ 隐式SQL的游标属性
        
        
         我们可以通过游标的属性去访问最近执行的SQL信息

                     

 

         如果会话还没有执行过隐式游标,所有的隐式游标属性都会返回NULL
         否则,返回的就是最后一次执行的SQL语句的属性值,而不管这个SQL在哪个代码块或程序中执行
         要想确保检查的确实是正确SQL语句的属性值,我们应该在该SQL语句执行之后立即把属性值保存到局部变量中

     PROCEDURE show_book_count
     IS
       l_count pls_integer;
       l_numfound pls_integer;
     BEGIN
       SELECT count(*) INTO l_count FROM books
       
       --对属性值作一个快照
       l_numfound := SQL%ROWCOUNT;
       
       update books set ....
       
       DBMS_OUTPUT.PUTLINE(l_numfound);
     END;
     

 

抱歉!评论已关闭.