zbb20170601 oracle PL/SQL 语句块 游标 自定义游标 异常处理EXCEPTION

--打开日志输出
set serverout on

-- PL/SQL 语句块:

-- 声明部分
declare
   v_i number;
   v_sum number:=0;
-- 执行部分
begin
  v_i := 1;
  -- 简单loop循环
  loop
    v_sum:=v_sum+v_i;
    v_i:=v_i+1;
    if v_i>100 then
      exit;-- 跳出循环
    end if;
  end loop;

  dbms_output.put_line(v_sum);

-- 异常处理部分
end;

-- 循环1 :简单LOOP循环
loop
  -- 循环体
end loop;
-- 退出循环:
if 退出条件 then
  exit;
end if;

-- 简写的退出条件
exit when 退出条件;

--
declare
     v_s number:=1;
     v_i number:=1;
begin
  loop
    v_s:=v_s*v_i;
    v_i:=v_i+1;
    exit when v_i>3;
  end loop;
  dbms_output.put_line(v_s);
end;
-- 注意:在sqlplus中要输出,需要打开输出标记:
--  SQL> set serveroutput on;

-- if语句
if 条件1 then
   --条件1为true执行语句
elsif 条件2 then
  --条件2为true执行语句
else
  --条件1、条件2都为false时执行语句
end if;

-- 循环2:while循环
declare
   v_i number:=1;
   v_sum number:=0;
begin
   while v_i<=100 loop
     v_sum:=v_sum+v_i;
     v_i:=v_i+1;
   end loop;  

   dbms_output.put_line(v_sum);
end;

-- 循环3:数值循环for
declare
   v_sum number:=0;
begin
   for v_i in  1..100 loop
     v_sum:=v_sum+v_i;
   end loop;

   dbms_output.put_line(v_sum);
end;

-- in reverse 反向for循环
begin
  for v_i in REVERSE 1..10 loop
    dbms_output.put_line(v_i);
  end loop;
end;

-- 查询
declare
   v_eno number:=7780;
   v_ename varchar2(20);
begin
  select ename into v_ename from emp where empno=v_eno;
  dbms_output.put_line(v_ename);

  exception
         when no_data_found then
           dbms_output.put_line(‘没找到数据异常:‘||sqlerrm);
         when others then-- others 相当于异常父类,可以捕获所有异常
           dbms_output.put_line(‘异常:‘||sqlerrm);
end;

-- 异常消息格式:
-- 异常类型(ORA运行异常  PLS编译异常) 异常编号(一个负数:-1 ~ -19999) 异常消息
-- 例如:ORA-01403: 未找到任何数据

-- 自定义异常:
--   my_exception_name EXCEPTION;  -- 定义异常名称
--  PRAGMA EXCEPTION_INIT(my_exception_name,-2290); -- 为异常编号困绑这个名称

declare
   my_exception_name EXCEPTION;  -- 定义异常名称
   PRAGMA EXCEPTION_INIT(my_exception_name,-2291); -- 为异常编号困绑这个名称
begin
  insert into emp(empno,deptno) values(1000,50);

  exception when my_exception_name then
    dbms_output.put_line(sqlerrm);
end;

-- 手动抛出异常:raise_application_error(异常编号,‘异常消息‘);

declare
   -- 嵌套语句块的外部声明部分
begin
  -- 嵌套前
declare
  -- 变量的声明周期:在其定义的begin end 中
   v_sex varchar2(20);
begin
  v_sex := ‘&输入性别‘;
  if not (v_sex = ‘男‘ or v_sex=‘女‘) then
    -- 抛出异常
    raise_application_error(-20000,‘性别只能是男或者女‘);
  end if;
  -- 正常输出语句
  dbms_output.put_line(‘性别:‘||v_sex);

  exception when others then
    dbms_output.put_line(sqlerrm);
end;

 -- 嵌套后
end;

-- 列引用类型:%type
declare
   v_ename emp.ename%type;
   v_sal emp.sal%type;
   c_constant constant number:=20;-- 定义一个常量
begin
  select ename,sal into v_ename,v_sal from emp where empno=&员工编号;
  dbms_output.put_line(v_ename||‘  ‘||v_sal);
  exception when others then
    dbms_output.put_line(sqlerrm);
end;

-- 行引用类型: %rowtype;
declare
 v_row emp%rowtype;
begin
  select * into v_row from emp where empno=&eno;
  dbms_output.put_line(v_row.ename||‘  ‘||v_row.empno||‘  ‘||v_row.sal||‘  ‘||v_row.deptno);
  exception when others then
    dbms_output.put_line(sqlerrm);
end;

--------- 游标 ----------
declare
    v_row emp%rowtype;
    -- 1-定义游标
    cursor cur_emp is select * from emp where deptno=10;
begin
  -- 2- 打开游标
  open cur_emp;
  loop
       -- 3- 提取数据
       fetch cur_emp into v_row;
       -- 提取不到数据时结束循环
       exit when cur_emp%notfound;

       dbms_output.put_line(v_row.empno||‘  ‘||v_row.ename||‘  ‘||v_row.deptno||‘  ‘||v_row.sal);

  end loop;

  -- 4- 关闭游标
  close cur_emp;

  exception when others then
    dbms_output.put_line(sqlerrm);

end;
/**
游标属性
    %found    boolean 测试是否提取到数据
    %notfound boolean 测试是否未提取到数据
    %isopen   boolean 测试是否打开
    %rowcount number  测试当前操作的行数
*/
-- while使用游标
declare
   cursor cur_emp is select * from emp where deptno=&dno;
   v_row emp%rowtype;
begin
  if not cur_emp%isopen then
     open cur_emp;
  end if;
  fetch cur_emp into v_row;
  while cur_emp%found loop
    dbms_output.put_line(cur_emp%rowcount||‘  ‘||v_row.empno||‘  ‘||v_row.ename||‘  ‘||v_row.deptno||‘  ‘||v_row.sal);
    fetch cur_emp into v_row;
  end loop;

  if cur_emp%isopen then
     close cur_emp;
  end if;

  exception when others then
    dbms_output.put_line(sqlerrm);
end;

-- 游标for循环:
--  特点:帮我们做 open fetch close
declare
    cursor cur_emp_dept is
           select e.empno,e.ename,e.deptno,d.dname,d.loc
           from emp e join dept d on(e.deptno=d.deptno);
   -- 使用游标定义行引用类型
    v_row cur_emp_dept%rowtype;
begin
  for v_row in cur_emp_dept loop
    dbms_output.put_line(v_row.empno||‘  ‘||v_row.ename||‘  ‘||v_row.deptno||‘  ‘||v_row.dname||‘  ‘||v_row.loc);
  end loop;

  exception when others then
    dbms_output.put_line(sqlerrm);

end;

-- 使用游标for循环甚至可以不用定义游标
begin
   for v_row in (select ename,sal from emp where deptno=20) loop
     dbms_output.put_line(v_row.ename||‘  ‘||v_row.sal);
   end loop;
end;

-- 参数化游标
declare
   -- 注意:形参禁止带精度,否则编译错误
   cursor cur_emp(dno number) is select * from emp where deptno=dno;
   v_row cur_emp%rowtype;
begin
  -- 打开游标时指定参数
  open cur_emp(30);
  fetch cur_emp into v_row;
  while cur_emp%found loop
    dbms_output.put_line(v_row.ename||‘  ‘||v_row.sal||‘  ‘||v_row.deptno);
    fetch cur_emp into v_row;
  end loop;
  close cur_emp;
  exception when others then
    dbms_output.put_line(sqlerrm);

end;

declare
   -- 注意:形参禁止带精度,否则编译错误
   cursor cur_emp(dno number) is select * from emp where deptno=dno;
begin

   for v_row in cur_emp(20) loop
     dbms_output.put_line(v_row.ename||‘  ‘||v_row.sal||‘  ‘||v_row.deptno);
   end loop;

  exception when others then
    dbms_output.put_line(sqlerrm);
end;

-- 游标的意义:逐行判断复杂的条件,并更新

-- 更新10部门工资低于3000的人,工资上涨10%;
declare

   cursor cur_emp is
          select * from emp
          for update  -- 锁定游标指定的结果集
          nowait;     -- 指定非等待方式
begin
  for v_row in cur_emp loop
    if(v_row.sal<3000 and v_row.deptno=10) then
                                         -- 条件: 游标指向的当前行
         update emp set sal=sal*1.1 where current of cur_emp;
    end if;
  end loop;

  exception when others then
    dbms_output.put_line(sqlerrm);
end;

-- 涉及多表操作的更新游标
declare

   cursor cur_emp is
          select e.*,d.dname,d.loc from emp e,dept d where d.deptno=e.deptno
          for update  -- 锁定游标指定的结果集
          of e.deptno -- 指定锁定emp表(结果集合使用emp的rowid)
          nowait;     -- 指定非等待方式
begin
  for v_row in cur_emp loop
    if(v_row.sal<3000 and v_row.deptno=10) then
                                         -- 条件: 游标指向的当前行
         update emp set sal=sal*1.1 where current of cur_emp;
    end if;
  end loop;

  exception when others then
    dbms_output.put_line(sqlerrm);
end;

-- 游标变量
declare
   -- 定义游标类型
   type my_cursor_type is ref cursor;
   -- 使用游标类型定义游标变量
   my_cursor my_cursor_type;

   v_row emp%rowtype;

   -- 错误:不能使用普通的游标变量定义行引用类型
   --v_row my_cursor%rowtype;
begin
  -- 打开游标时赋予结果集
  open my_cursor for select * from emp;

  loop
    fetch my_cursor into v_row;
    exit when my_cursor%notfound;
    dbms_output.put_line(v_row.empno||‘  ‘||v_row.ename||‘  ‘||v_row.deptno||‘  ‘||v_row.sal);
  end loop;
  close my_cursor;

  exception when others then
    dbms_output.put_line(sqlerrm);
end;

-- 定义一个带返回类型的游标类型,生成游标变量
declare
   -- 定义带返回类型的游标类型
   type my_cursor_type is ref cursor return emp%rowtype;
   -- 使用游标类型定义游标变量
   my_cursor my_cursor_type;

   --v_row emp%rowtype;

   -- 正确:可以使用带返回类型的游标变量定义行引用类型
   v_row my_cursor%rowtype;
begin
  -- 打开游标时赋予结果集
  open my_cursor for select * from emp;

  loop
    fetch my_cursor into v_row;
    exit when my_cursor%notfound;
    dbms_output.put_line(v_row.empno||‘  ‘||v_row.ename||‘  ‘||v_row.deptno||‘  ‘||v_row.sal);
  end loop;
  close my_cursor;

  exception when others then
    dbms_output.put_line(sqlerrm);
end;

type cur is ref cursor;

整体的意思是“创建一个类型变量cur,它引用游标”,除了cur外,其余全是关键字。
TYPE cur:定义类型变量
is ref cursor:相当于数据类型,不过是引用游标的数据类型。
这种变量通常用于存储过程和函数返回结果集时使用,因为PL/SQL不允许存储过程或函数直接返回结果集,但可以返回类型变量,于是引用游标的类型变量作为输出参数或返回值就应运而生了
时间: 2024-10-28 14:18:28

zbb20170601 oracle PL/SQL 语句块 游标 自定义游标 异常处理EXCEPTION的相关文章

[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)

原文:[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之四: 把游标说透(不怕做不到,只怕想不到) 继上两篇:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) 得到了大家的强力支持,感谢.接下来再下猛药,介绍下一篇,大家一定要支持与推荐呀~!我也才有动力写后面的. 本篇主要内容如下: 4.1 游标概念 4.1.1 处理显式游标 4.1.2 处理

SQLPLUS执行PL/SQL语句块

1.首先登录Oracle HR schema: 2.对于PL/SQL程序,分号表示语句的结束:而使用 "."  号表示整个语句块的结束,也可以省略.按回车键后,该语句块不会执行,即不会发送到数据库服务器,而是必须使用 "/" 符号执行PL/SQL 语句块 使用 "/" 执行PL/SQL 语句块 3. 在上例中,虽然执行了PL/SQL 程序,但是没有输出结果的显示.数据库服务器肯定将数据传输给了SQLPLUS,并且变量var_first_name

Oracle PL/SQL语句基础学习笔记(上)

PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL/SQL整合到ORACLE server和其它工具中了,近几年中很多其它的开发者和DBA開始使用PL/SQL,本文将讲述PL/SQL基础语法,结构和组件.以及怎样设计并运行一个PL/SQL程序. 1.PL/SQL的长处 从版本号6開始PL/SQL就被可靠的整合到ORACLE中了,一旦掌握PL/SQL的长处以及其独有的数据管理的便利性,那么你非常难想象ORACLE缺了PL/SQL的情形.PL/SQL 不是一个独立的产品,他

[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日之功) 继上四篇:ORACLE PL/SQL编程之八:把触发器说透                ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)                [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]

[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) 得到了大家的强力支持与建议,万分感谢.接下来介绍下一篇:oracle pl/sql异常处理部分,还望大家一定

[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)

原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天才在于积累!) ——通过知识共享树立个人品牌.   继上七篇:            [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)            [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之

【转】[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

[推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) 得到了大家的强力支持与建议,万分感谢.接下来介绍下一篇:oracle pl/sql异常处理部分,还望大家一定要支持与推荐呀~! 本篇主要内容如下: 5.1 异常处理概念 5.1.1 预定义的异常

ORACLE PL/SQL编程详解

ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设计语言,该语言专门用于在各种环境下对ORACLE数据库进行访问.由于该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理.除此之外,可以在ORACLE数据库的某些客户端工具中,使用PL/SQL语言也是该语言的一个特点.本章的主要内容是讨论引入PL/SQL语言的必要性和该语言的

【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航

原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人品牌. 本是成书的,但后来做其他事了,就无偿的贡献出来,被读者夸其目前为止最“实在.经典”的写ORACLE PL/SQL编程的文章-! 觉得对你有帮助,请留言与猛点推荐,谢谢. [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) 本篇主要内容如下:第一章 PL/S