sql游标 例子

来源:互联网 发布:js中NaN 编辑:程序博客网 时间:2024/05/16 05:43
/*******************
游标
Oracle打开一个工作区来保存多行查询的结果集,游标就是给这个工作区命的名称,并能用于处理由多行查询而返回的记录行。
隐式游标:所有的DML语句和PL/SQL SELECT 语句都有
显式游标:由开发人员声明和控制
%ISOPEN Boolean游标打开,则返回True
%NOTFOUND Boolean如果最近抓取没有获得记录,返回True
%FOUND Boolean 如果最近抓取获得记录,返回True
%ROWCOUNT Number返回到目前为止获取的记录数


步骤:
1.定义游标
2.打开游标
3.循环提取数据
4.关闭游标
*******************/
SELECT * FROM tb_student;


--1. 提取tb_student的所有数据    不要写
DECLARE
--定义一个游标,存储查询的结果
  CURSOR c_tb_student
  IS
  SELECT * FROM tb_student;
  --定义rowtype
  r_student tb_student%ROWTYPE;
BEGIN
  OPEN c_tb_student;  --如果游标已经打开,不能再打开,会报错
  --游标指针默认指向数据第一行,每次fetch向下移动一行,如果到最后一行了,则每次提取都是最后一行数据
  FETCH c_tb_student INTO r_student;
  dbms_output.put_line('id: ' || r_student.id);
   dbms_output.put_line('name: ' || r_student.name);
   
   FETCH c_tb_student INTO r_student;
  dbms_output.put_line('id: ' || r_student.id);
   dbms_output.put_line('name: ' || r_student.name);
   
    FETCH c_tb_student INTO r_student;
  dbms_output.put_line('id: ' || r_student.id);
   dbms_output.put_line('name: ' || r_student.name);
  CLOSE c_tb_student; --关闭游标
END;




--重点  多写几百遍
--使用循环提取所有表数据
DECLARE
--定义一个游标,存储查询的结果
  CURSOR c_tb_student
  IS
  SELECT * FROM tb_student;
  --定义rowtype
  r_tb_student tb_student%ROWTYPE;
BEGIN
  OPEN c_tb_student;
       LOOP
         FETCH c_tb_student INTO r_tb_student;  --提取数据
         EXIT WHEN c_tb_student%NOTFOUND;   --当游标无可提取数据返回true,则退出循环
         dbms_output.put_line('id: ' || r_tb_student.id);
         dbms_output.put_line('name: ' || r_tb_student.name);
       END LOOP;
  CLOSE c_tb_student;
END;


SELECT * FROM tb_clazz;
SELECT * FROM tb_student WHERE clazz_id = ?
--SELECT * FROM tb_student FOR UPDATE;
--提取所有班级信息,同时将每个班级的学生信息提取出来
--带参数的游标
DECLARE
--定义班级的游标和rowtype
    CURSOR c_tb_clazz IS SELECT * FROM tb_clazz;
    r_tb_clazz tb_clazz%ROWTYPE;
--定义学生的游标和rowtype,型参的数据类型不需要加长度
   CURSOR c_tb_student(v_clazz_id INT) IS SELECT * FROM tb_student WHERE clazz_id=v_clazz_id;
   r_tb_student tb_student%ROWTYPE;
   --异常处理变量
    v_code VARCHAR2(50);
    v_message VARCHAR2(200);
BEGIN
   OPEN c_tb_clazz;
        LOOP
          FETCH c_tb_clazz INTO r_tb_clazz;
          EXIT WHEN c_tb_clazz%NOTFOUND;
          dbms_output.put_line('班级id: ' || r_tb_clazz.id ||'   编号:'|| r_tb_clazz.code);
          --根据班级id查询班级的学生信息
          OPEN c_tb_student(r_tb_clazz.id);
               LOOP
                 FETCH c_tb_student INTO r_tb_student;
                 EXIT WHEN c_tb_student%NOTFOUND;
                 dbms_output.put_line('学生id: ' || r_tb_student.id ||'   姓名:'|| r_tb_student.name);
               END LOOP;
          CLOSE c_tb_student;
           dbms_output.put_line('---------------------------------------------------');
        END LOOP;   
   CLOSE c_tb_clazz;
   --处理异常
  EXCEPTION
    WHEN OTHERS THEN
     -- SQLCODE:返回错误代码
     --SQLERRM:返回与错误代码关联的消息
       v_code := SQLCODE;
       v_message:=SQLERRM;
       INSERT INTO tb_error(ID,object,code,message,currdate)
       VALUES(seq_tb_error.nextval,'testplsql',v_code,v_message,SYSDATE);
       COMMIT;
END;









0 0