`
regedit_123
  • 浏览: 323382 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

PLSQL游标和goto语句

阅读更多

*****************************************
  PLSQL游标和goto语句
*****************************************
备注:下面提到的游标为静态cursor,包括显示和隐式
游标,从declare、open、fetch、close是一个完整的生命旅程。当然了一个这样的游标是可以被多次open进行使用的,显式cursor是静态cursor,她的作用域是全局的,但也必须明白,静态cursor也只有pl/sql代码才可以使用它。

静态游标变量是在定义时就必须指定SQL语句。

cursor 游标(结果集)用于提取多行数据,定义后不会有数据,使用后才有。一旦游标被打开,就无法再次打开(可以先关闭,再打开)。


 第一种游标的定义方式

   declare
          cursor c_student is  select * from book;
    begin
          open c_student;
          close c_student;
    end;

第二种游标的定义方式,用变量控制结果集的数量。
    declare
          v_id binary_integer;
          cursor c_student is select * from book where id>v_id;
    begin
          v_id:=10;
          open c_student;
          close c_student;
    end;

第三种游标的定义方式,带参数的游标,用的最多。
    declare
          cursor c_student(v_id binary_integer) is select * from book where id>v_id;
    begin
          open c_student(10);
          close c_student;
    end;

 

游标的使用,一定别忘了关游标。
    declare
          v_student emp%rowtype;
          cursor c_student(v_id binary_integer) is select * from emp where rownum<v_id;
    begin
          open c_student(10);
          fetch c_student into v_student;
          close c_student;
          dbms_output.put_line(v_student.name);
    end;


如何遍历游标fetch
  游标的属性 %found,%notfound,%isopen,%rowcount。
  %found:若前面的fetch语句返回一行数据,则%found返回true,如果对未打开的游标使用则报ORA-1001异常。
  %notfound,与%found行为相反。
  %isopen,判断游标是否打开。
  %rowcount:当前游标的指针位移量,到目前位置游标所检索的数据行的个数,若未打开就引用,返回ORA-1001。

注:
no_data_found和%notfound的用法是有区别的,小结如下
1)SELECT . . . INTO 语句触发 no_data_found;
2)当一个显式光标(静态和动态)的 where 子句未找到时触发 %notfound;
3)当UPDATE或DELETE 语句的where 子句未找到时触发 sql%notfound;
4)在光标的提取(Fetch)循环中要用 %notfound 或%found 来确定循环的退出条件,不要用no_data_found。

 

下面是几个实例:
create table BOOK
(
  ID       VARCHAR2(10) not null,
  BOOKNAME VARCHAR2(10) not null,
  PRICE    VARCHAR2(10) not null,
  CID      VARCHAR2(10) not null
);

 

--insert
create or replace procedure say_hello(
i_name in varchar2,
o_result_msg out varchar2
)
     as
     v_price varchar2(100);
     e_myException exception;

     begin
        insert into book(id,bookname,price) values (1,2,3);
        o_result_msg := 'success';
     exception
        when others then
             rollback;
             o_result_msg := substr(sqlerrm, 1, 200);
     end;

 

--update or delete
create or replace procedure say_hello(
i_name in varchar2,
o_result_msg out varchar2
)
     as
     v_price varchar2(100);
     e_myException exception;

     begin
        update book set price = '55' where bookname = i_name;
        delete from book where bookname = i_name;
        if sql%notfound then
           raise e_myException;
        end if;
        /*
 if sql%rowcount = 0 then--写法2
           raise e_myException;
        end if;
 */
        o_result_msg := 'success';
     exception
        when e_myException then
             rollback;
             o_result_msg := 'update or delete dail';
     end;

 

--select
create or replace procedure say_hello(
i_name in varchar2,
o_result_msg out varchar2
)
     as
     v_price varchar2(100);
     e_myException exception;

     begin
        select price into v_price from book where bookname = i_name;
        o_result_msg := 'success';
     exception
        when no_data_found then
             rollback;
             o_result_msg := 'select into dail';
     end;

loop方式遍历游标
    declare
          v_bookname  varchar2(100);
          cursor c_book(i_id number) is select bookname from book where id = i_id;
    begin
        Open  c_book(i_id);
        Loop
            Fetch c_book into v_bookname;
            exit when c_student%notfound;
              update book set price = '33' where bookname = v_bookname;
        End Loop;
        Close c_book;
    end;
   
    declare
          v_bookname  varchar2(100);
          cursor c_book(i_id number) is select bookname from book where id = i_id;
    begin
        Open  c_book(i_id);
          Fetch c_book into v_bookname;
          While c_book%Found
          Loop
              update book set price = '33' where bookname = v_bookname;
          Fetch  c_book into v_bookname;
          End Loop;
        Close c_book;
    end;
       

while循环遍历游标,注意,第一次游标刚打开就fetch,%found为null,进不去循环
解决方法:while nvl(c_student%found,true) loop
    declare
         v_bookname  varchar2(100);
         cursor c_book(i_id number) is select bookname from book where id = i_id;
    begin
         Open  c_book(i_id);
         while nvl(c_book%found,true) --或这种写法:while c_book%found is null or c_book%found loop   
             Fetch c_book into v_bookname;
             update book set price = '33' where bookname = v_bookname;
         End Loop;
         Close c_book;
    end;

 

for循环遍历,最简单,用的最多,不需要 声明v_student,Open和Close游标和fetch操作(不用打开游标和关闭游标,实现遍历游标最高效方式)
    declare
         cursor c_book(i_id number) is select bookname from book where id = i_id;
    begin
         for cur in c_book(i_id) --直接将入参i_id传入cursor即可
         loop
             update book set price = '53' where bookname = cur.bookname;
         end loop;
    end;

goto例子,一般不推荐使用goto,会使程序结构变乱
    declare
         i number:=0;
    begin
         if i=0 then
             goto hello;
         end if;
         <<hello>>
         begin
             dbms_output.put_line('hello');
             goto over;
         end;
         <<world>>
         begin
             dbms_output.put_line('world');
             goto over;
         end;
         <<over>>
             dbms_output.put_line('over');
     end;

附:

declare
          cursor c_student(v_id binary_integer) is select * from emp where rownum < v_id;
    begin
          for cur in c_student(10)
          loop  
          dbms_output.put_line(cur.ename);
            end loop;

    end;

分享到:
评论

相关推荐

    数据库oracle中PLSQL语句简介及使用方法的举例说明

    PL/SQL提供了一系列的流程控制语句,如IF...THEN...ELSIF...ELSE...END IF用于条件判断,WHILE循环和FOR循环用于迭代,以及GOTO语句进行跳转。 五、PL/SQL的SQL语句 PL/SQL可以直接嵌入SQL语句,如SELECT、INSERT、...

    PLSQL高级编程-结构化编程

    3. GOTO语句虽然不推荐使用,但在某些特定场景下,可以提供无条件跳转的功能。 三、块结构 PLSQL中的块有四种类型:匿名块、存储过程、函数和包。匿名块是未命名的PLSQL代码块,通常用于测试和调试。存储过程和函数...

    PLSQL 个人自学总结

    执行部分是实际执行的代码,包括SQL语句和PLSQL语句;异常处理部分则用于捕获和处理运行时可能出现的错误。 1. 声明部分: 在PLSQL中,我们可以声明各种类型的变量,如NUMBER、VARCHAR2、DATE等。此外,也可以定义...

    PLSQL相关书籍(PDF)

    执行部分包含SQL语句和PLSQL语句;异常处理部分用于捕获和处理运行时错误。 2. **变量和数据类型**:PLSQL支持多种数据类型,包括数值型(如NUMBER)、字符型(如VARCHAR2、CHAR)、日期型(DATE)、布尔型...

    PLSQL.rar_plsql_plsql java

    4. **PLSQL的流程控制**:包括IF-THEN-ELSIF-ELSE语句、CASE语句、FOR循环、WHILE循环、GOTO跳转等,用于根据不同的条件执行不同的代码块。 5. **PLSQL的存储过程与函数**:存储过程是一组为了完成特定功能的SQL...

    plsql工具很好用

    执行部分则是编写SQL语句和过程化逻辑的地方;异常处理部分用于捕获和处理运行时可能发生的错误。 PLSQL支持多种数据类型,包括基本类型(如NUMBER、VARCHAR2、DATE等)、复合类型(如记录、数组)、对象类型以及PL...

    PLSQL用户指南与参考

    1. **PLSQL基础**:了解PLSQL的基本语法,包括变量声明、常量定义、条件语句(如IF-ELSE)、循环结构(如WHILE和FOR)、异常处理(如BEGIN-EXCEPTION-END)以及控制流程语句(如GOTO)。 2. **块的概念**:PLSQL由...

    PLSQL教程.rar

    执行部分包含SQL语句和PLSQL过程、函数、块;异常处理部分处理运行时可能出现的错误。 二、PLSQL的数据类型 PLSQL支持多种数据类型,包括数值类型(如NUMBER)、字符类型(如VARCHAR2、CHAR)、日期时间类型(如...

    PLSQL详细手册

    3. **流程控制语句**:包括条件语句(IF-THEN-ELSIF-ELSE)、循环语句(WHILE, FOR, GOTO)和CASE表达式,用于控制程序的执行流程。 4. **集合操作**:PLSQL中的集合包括数组、索引表(Index-By Table)和关联数组...

    PLSQL.pdf,学习oracle必备手册

    4. **控制流语句**:学习如何使用IF-THEN-ELSIF-ELSE、CASE、WHILE、FOR循环以及GOTO语句来控制程序的流程。 5. **SQL操作**:PLSQL可以嵌入SQL语句,用于查询、插入、更新和删除数据库中的数据。例如,你可以编写...

    PLSQL_2

    执行部分包含SQL语句和PLSQL语句,用于执行任务;异常处理部分则用于捕获和处理运行时错误。 2. **变量与数据类型**: 在PLSQL中,我们可以声明各种数据类型,包括数值型(如NUMBER)、字符型(如VARCHAR2)、日期...

    PLSQL user guide

    4. **流程控制**:包括条件语句(IF-THEN-ELSIF-ELSE)、循环(WHILE、FOR)、CASE语句和GOTO语句,用于实现复杂的逻辑控制。 5. **集合和记录**:PLSQL提供数组(PL/SQL表)和记录类型,允许存储一组同类型的值或...

    Oracle PLSQL 从入门到精通

    执行部分是程序的主要逻辑,包含SQL语句和过程化语句;异常处理部分则用于捕获和处理运行时可能出现的错误。 PLSQL中的数据类型是学习的重点之一,包括内置的数值类型(如NUMBER、INTEGER)、字符类型(VARCHAR2、...

    PLSQL程序设计

    执行部分包含SQL语句和PLSQL控制结构;异常处理部分则用于捕获和处理运行时错误。 二、变量与数据类型 PLSQL支持多种内置数据类型,如NUMBER、VARCHAR2、DATE、BOOLEAN等。理解这些数据类型的特性和使用场景是编写...

    PLSQL程序结构.rar

    PLSQL的语句以分号结束,支持条件语句(如IF-THEN-ELSIF-ELSE)、循环语句(如WHILE、FOR)以及流程控制语句(如GOTO)。 视图是PLSQL中的一个重要概念,它是从一个或多个表中选择数据的结果集,可以被当作一个虚拟...

    PLSQL基础(中文版)

    3. **分支语句**:GOTO语句可以实现无条件跳转,但通常不推荐使用,因为可能会导致代码难以维护。 4. **退出语句**:EXIT和CONTINUE语句用于提前退出循环或跳过当前迭代。 **五、SQL嵌入** PL/SQL可以直接嵌入SQL...

    PLSQL

    执行部分包含SQL语句和PLSQL语句;异常处理部分用于捕获和处理运行时错误。 2. 变量和常量:在PLSQL中,可以声明各种类型的变量,如整型、浮点型、字符型、日期型等,以及常量,它们在程序执行过程中可被赋值和修改...

    深入浅出plsql,绝对精品

    - **分支语句**:GOTO用于无条件跳转到程序中的另一位置,但通常不推荐使用,因为可能造成代码难以理解和维护。 3. **函数与过程**: - **函数**:返回一个值的PLSQL子程序,可以被其他PLSQL代码或SQL查询调用。 ...

    PLSQL Oracle8i程序设计

    PLSQL提供了多种流程控制结构,如IF-THEN-ELSE、CASE语句用于条件判断,WHILE和FOR循环用于迭代,GOTO语句进行无条件跳转,以及LOOP结构用于自定义循环。 四、SQL操作 PLSQL可以直接嵌入SQL语句,进行数据查询、...

    PLSQL语言(一)

    执行部分包含SQL语句和PLSQL语句,用于执行数据操作;异常处理部分则用于捕获和处理运行时可能出现的错误。 1. **变量和数据类型**:在PLSQL中,我们可以声明各种变量,包括数值类型(如NUMBER)、字符串类型(如...

Global site tag (gtag.js) - Google Analytics