Oracle游标(光标)



watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGFuZ2xpdXFpbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >

表、select语句、游标:返回结果都能是一个集合。

注意:游标的结果是一个集合。

--查询并打印员工的姓名和薪水
set serveroutput on
/*
光标:
1. 光标的属性: %isopen    %rowcount(返回的行数)
              %notfound  %found

2. 默认情况下。一次性打开300个光标
SQL> show parameter  cursor

NAME                                 TYPE        VALUE
------------------------------------ ----------- ---------------
cursor_sharing                       string      EXACT
cursor_space_for_time                boolean     FALSE
open_cursors                         integer     300
session_cached_cursors               integer     20

改动光标:
alter system set open_cursors=400;
*/
declare
  --定义一个光标
  cursor cemp is select ename,sal from emp;
  pename emp.ename%type;引用变量
  psal   emp.sal%type;引用变量
begin
  open cemp;
  loop
    --取一条记录
    fetch cemp into pename,psal;
    --退出: fetch没有取到
    exit when cemp%notfound;

    dbms_output.put_line(pename||'的薪水是'||psal);

  end loop;
  close cemp;
end;
/
--查询某个部门的员工姓名
set serveroutput on

declare
  cursor cemp(dno number) is select ename from emp where deptno=dno;
  pename emp.ename%type;
begin
  open cemp(20);
  loop
    fetch cemp into pename;
    exit when cemp%notfound;

    dbms_output.put_line(pename);

  end loop;
  close cemp;
end;
/
/*
SQL语句
select to_char(hiredate,'YYYY') from emp
--> 光标 --> 循环 --> 退出条件

变量:
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
*/
set serveroutput on
declare
  cursor cemp is select to_char(hiredate,'YYYY') from emp;
  phiredate varchar2(4);

  count80 number := 0;
  count81 number := 0;
  count82 number := 0;
  count87 number := 0;
begin
  open cemp;
  loop
    --取一个员工的年份
    fetch cemp into phiredate;
    exit when cemp%notfound;

    --推断年份
    if phiredate = '1980' then count80 := count80+1;
      elsif phiredate = '1981' then count81 := count81+1;
      elsif phiredate = '1982' then count82 := count82+1;
      else count87 := count87 + 1;
    end if;
  end loop;
  close cemp;

  --输出
  dbms_output.put_line('Total:'||(count80+count81+count82+count87));
  dbms_output.put_line('1980:'||count80);
  dbms_output.put_line('1981:'||count81);
  dbms_output.put_line('1982:'||count82);
  dbms_output.put_line('1987:'||count87);
end;
/
/*
SQL语句:
select empno,sal from emp order by sal
--> 光标 --> 循环  --> 退出条件: 1. 总额> 5w  2. 全部人涨完

变量:
涨工资的人数: countEmp number := 0;
涨后的工资总额: salTotal number;
                1. select sum(sal) into salTotal from emp;
                2. 涨后 = 涨前 + sal * 0.1

练习: 工资总额不能超过5w
*/
set serveroutput on
declare
  cursor cemp is select empno,sal from emp order by sal;
  pempno emp.empno%type;
  psal   emp.sal%type;
  --涨工资的人数:
  countEmp number := 0;

  --涨后的工资总额:
  salTotal number;
begin
  --得到工资初始值
  select sum(sal) into salTotal from emp;
  open cemp;
  loop
    --1. 总额> 5w
    exit when salTotal > 50000;
    --取一个员工
    fetch cemp into pempno,psal;
    --2. 全部人涨完
    exit when cemp%notfound;

    --涨工资
    update emp set sal=sal*1.1 where empno=pempno;
    --人数+1
    countEmp := countEmp +1;
    --总额
    salTotal := salTotal + psal * 0.1;
  end loop;
  close cemp;

  commit;
  dbms_output.put_line('人数:'||countEmp||'   涨后的工资总额:'||salTotal);
end;
/
/*
SQL语句:
部门: select deptno from dept --> 光标 --> 循环  --> 退出条件
部门中员工的薪水: select sal from emp where deptno=??
                  --> 带參数的光标 --> 循环  --> 退出条件

变量:
每一个段的人数:
count1 number; count2 number; count3 number;
部门的工资总额:
salTotal number;
1. 累加
2. select sum(sal) into salTotal from emp where deptno=?

?

*/
set serveroutput on
declare
  --部门
  cursor cdept is select deptno from dept;
  pdeptno dept.deptno%type;

  --部门中员工的薪水
  cursor cemp(dno number) is select sal from emp where deptno=dno;
  psal emp.sal%type;

  --每一个段的人数:
  count1 number; count2 number; count3 number;

  --部门的工资总额:
  salTotal number;
begin
  open cdept;
  loop
    --取一个部门
    fetch cdept into pdeptno;
    exit when cdept%notfound;
    --初始化
    count1:=0; count2:=0; count3:=0;
    --部门的工资总额
    select sum(sal) into salTotal from emp where deptno=pdeptno;
    --部门中员工的薪水
    open cemp(pdeptno);
    loop
      -- 取一个员工的薪水
      fetch cemp into psal;
      exit when cemp%notfound;

      --推断薪水
      if psal < 3000 then count1:=count1+1;
        elsif psal>=3000 and psal< 6000 then count2:=count2+1;
        else count3:=count3+1;
      end if;

    end loop;
    close cemp;

    --保存当前部门
    insert into msg values(pdeptno,count1,count2,count3,nvl(salTotal,0));

  end loop;
  close cdept;
  commit;

  dbms_output.put_line('完成');
end;
/
时间: 2024-12-09 15:17:40

Oracle游标(光标)的相关文章

[转载]oracle游标概念讲解

原文URL:http://www.2cto.com/database/201203/122387.html ORACLE游标概念讲解 什么是游标?  ①从表中检索出结果集,从中每次指向一条记录进行交互的机制.      ②关系数据库中的操作是在完整的行集合上执行的.   由SELECT 语句返回的行集合包括满足该语句的WHERE 子句所列条件的所有行.由该语句返回完整的行集合叫做结果集.      应用程序,尤其是互动和在线应用程序,把完整的结果集作为一个单元处理并不总是有效的.      这些

【翻译】Oracle游标详细说明

这篇文章是选取官方文档的部分章节翻译过来的,去除了原文中的例子,并在结尾补充了几个例子.有兴趣的朋友可以点击文章末尾的连接去阅读官方文档. 一.游标的定义 游标是指向专用SQL区域的指针,该区域存储有关处理特定SELECT或DML语句的信息.本章解释的游标是会话游标.会话游标存在于会话中直到会话结束.由PL/SQL创建和管理的游标称为隐式游标,由用户创建和管理的游标称为显式游标.你可以通过游标的属性获取任意会话游标的相关信息.通过查询动态性能视图V$OPEN_CURSOR,可以列出当前已经打开和

oracle 游标 学习

1,什么是游标? ①从表中检索出结果集,从中每次指向一条记录进行交互的机制. ②关系数据库中的操作是在完整的行集合上执行的.  由 SELECT 语句返回的行集合包括满足该语句的 WHERE 子句所列条件的所有行.由该语句返回完整的行集合叫做结果集.  应用程序,尤其是互动和在线应用程序,把完整的结果集作为一个单元处理并不总是有效的. 这些应用程序需要一种机制来一次处理一行或连续的几行.而游标是对提供这一机制的结果集的扩展. 游标是通过游标库来实现的.游标库是常常作为数据库系统或数据访问 API

ORACLE游标概念讲解

1,什么是游标? ①从表中检索出结果集,从中每次指向一条记录进行交互的机制. ②关系数据库中的操作是在完整的行集合上执行的.   由 SELECT 语句返回的行集合包括满足该语句的 WHERE 子句所列条件的所有行.由该语句返回完整的行集合叫做结果集.      应用程序,尤其是互动和在线应用程序,把完整的结果集作为一个单元处理并不总是有效的.      这些应用程序需要一种机制来一次处理一行或连续的几行.而游标是对提供这一机制的结果集的扩展.      游标是通过游标库来实现的.游标库是常常作

Duang!危险的oracle游标

1.引言 SQL是面向集合的语言,其结果一般是集合量(含多条记录),而pl/sql的变量是标量,一组变量一次只能存放一条记录.很多时候查询结果的记录数是不确定的,无法提前声明足够的变量.于是引入了游标的概念,游标使得数据库操作更灵活,但同时也给黑客入侵数据库带来了机会.安华金和数据库安全实验室(DBSec Labs)基于游标的应用原理,本文讨论游标可能带来什么安全隐患以及如何应对这些安全隐患. 2.游标的分类 oracle数据库游标是Pl/sql执行DQL.DML等语句的时候,oracle在内存

oracle 游标例子

CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS(RETCODE OUT VARCHAR2) /*********************************************************** * 功能:WAP指标--活跃用户统计(分批提交) * 参数:RETCODE(返回编码:0000成功) * 作者: * 创建时间:2013-01-16 * 版本:1.0 * 修改人: * 修改时间: ********************

Oracle游标—for、loop、if结合应用

一.需求 什么时候会用到Oracle游标,以及其中的for.loop.if呢? 先看这样一个需求: 有一张学生授课表T_TEACHING,每个学生都有数门课程: 主键ID(自增) 课程号COURSE_ID 学号USER_ID 1 01 201501 2 02 201501 3 03 201501 4 01 201502 5 01 201503 6 01 201504 7 02 201504 ... ... ... 但是因为某些原因,导致有的学生课程不全(本应该每个学生都有3门课),应该如何把不全

Oracle游标循环更新数据案例

declare v_XTXMBH number; v_ZJZJZJRQ varchar2(40); cursor c_job is SELECT XT.XTXMBH AS XTXMBH, QJ.ZJZJZJRQ AS ZJZJZJRQ FROM XTXMXX XT, QJGLXX_ZQL_MID QJ WHERE XT.XTXMBH = QJ.XTXMBH AND XT.XTXMCLRQ >= '20120630' AND (QJ.ZJQHZJRQ IS NULL OR QJ.ZJZJZJRQ

oracle游标小试

有时候需要大面积的修改数据,这个时候用循环语句效率不高.而临时表又不能满足点对点修改的时候,游标似一种不错的选择(PS:好像游标也是为循环而生的吧) 现在有两张表 t1(ryid number,name nvarchar2(50),salary number,paydate date……)用来存员工每月的工资 t2(ryid number,paySalary number)每个月发的工资数目 现将t2中的paySalary添加到t1中 可以直接用update来实现: 现用oracle的for游标

Oracle 游标示例,带异常处理

Oracle游标示例一则,带异常处理. DECLARE CURSOR c_dl IS SELECT ID, NSRSBH, WSPZXH, ZXYY_DM, HZRQ, SWJG_DM, GXSJ FROM T_GUOS_ZXXX WHERE gxsj > begin_gxsj; c_row c_dl%ROWTYPE; BEGIN FOR c_row IN c_dl LOOP BEGIN IF (c_row.GXSJ > max_gxsj) THEN BEGIN max_gxsj := c_r