博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle Class7. 异常和游标管理
阅读量:7126 次
发布时间:2019-06-28

本文共 7204 字,大约阅读时间需要 24 分钟。

------------------------2013-5-18------------------------

异常
raise_application_error:错误编号必须介于-20000和-20999之间
错误消息的长度可长达2048个字节。

游标类型

静态游标
  隐式游标 sql%found  sql%rowcount
  显式游标 cur_xxx%found
ref游标

游标属性

  %notfound
  %found
  %rowcount
  %isopen
控制显示游标
  open
  fetch
  close

循环游标 显式游标

  隐式打开游标
  自动从活动集获取行
  在处理完所有行时关闭游标
优点
  简化代码的编写

游标变量的类型:强游标,弱游标。

游标管理 限制

  不能在程序包中声明游标变量
  远程子程序不能接受游标变量的值
  不能使用比较操作符对游标变量进行相等或不相等测试
  不能将空值赋予游标变量
  表不能存储游标变量的值

-- 包
create or replace package pkg_Test
is
type type_title_rec is record             -- 可以理解为java里面的对象,可以作为参数来传递。--
(
Title c6.a%type,
Price c6.b%type
);

gc_Name_char constant varchar2(12) := 'AZhu';

gv_Age_num number := 18;

function FunGetTitleByTitleID (p_TitleID in c6.a%type) return type_title_rec;

procedure ProGetTitleByTitleID(p_TitleID in c6.a%type,lvv out type_title_rec);

end pkg_Test;

-- 包主体
create or replace package body pkg_Test
is
  function FunGetTitleByTitleID     -- 函数实现,没有create,如果是过程的话,procedure。
  (p_TitleID in c6.a%type)
  return type_title_rec
  as
  lv_title_rec type_title_rec;
  begin
    select a, b into lv_title_rec
    from c6
    where a = p_TitleID;
    return (lv_title_rec);
  end FunGetTitleByTitleID;
 
  procedure ProGetTitleByTitleID
  (p_TitleID in c6.a%type,
   lvv out type_title_rec 
  )
  as
  begin
    select a, b into lvv
    from c6
    where a = p_TitleID;
  end ProGetTitleByTitleID;

end pkg_Test;

set serveroutput on;   --打开输出,每次重起SQLPlus Worksheet需要重新打开输出。

-- 包函数调用

declare
lv_title_rec pkg_Test.type_title_rec;
begin
  lv_title_rec := pkg_Test.FunGetTitleByTitleID('2');  -- 包.函数名
  dbms_output.put_line(lv_title_rec.title);
  dbms_output.put_line(lv_title_rec.price);
end;

-- 包过程调用

declare
lv_title_rec pkg_Test.type_title_rec;
begin
  pkg_Test.ProGetTitleByTitleID('3',lv_title_rec);     -- 包.过程名
  dbms_output.put_line(lv_title_rec.title);
  dbms_output.put_line(lv_title_rec.price);
end;

-- 包中变量和常量的调用及修改值

begin
  dbms_output.put_line(pkg_Test.gv_Age_num);           -- 包.变量名
  dbms_output.put_line(pkg_Test.gc_Name_char);         -- 包.常量名
  pkg_Test.gv_Age_num := 28;
  dbms_output.put_line(pkg_Test.gv_Age_num);           -- 包.变量名
end;

 

where current of c;  -- 表示操作的是当前游标,可以做修改或删除。

 

create or replace function FunGetTitleByTitleID2     -- 函数实现,没有create,如果是过程的话,procedure。
  (p_TitleID in c6.a%type)
  return type_title_rec
  as

  lv_title_rec type_title_rec;

  begin
    select a, b into lv_title_rec
    from c6
    where a = p_TitleID;
    return (lv_title_rec);
  end;

create type add_type3 as object(
  street varchar2(10),  --街道名
  city varchar2(10),    --城市名
  state char(2),        --州代码
  zip   c6.b%type          --邮编     --c6.b%type这样写会报错。
);

 

create type type_title_rec as object    -- is record会报错。

(
  Title number,
  Price varchar2(10)
);

create or replace function FunGetTitleByTitleID2
  (p_TitleID in c6.a%type)
  return c6.a%type
  --return type_title_rec;          -- 返回类型在前,创建类型在后?会报错?
                                    -- 在包声明中都定义好了,在包体中可以直接使用了。--
  as
  type type_title_rec is record     -- is record会报错。
  (
    Title c6.a%type,
    Price c6.b%type
  );
  lv_title_rec type_title_rec;
  begin
    select a,b into lv_title_rec    -- 查询的值必须一一对应,否则报创建的函数带有编译错误。--
    from c6
    where a = p_TitleID;
    --return (lv_title_rec);
    return p_TitleID;
  end;

create or replace function FunGetTitleByTitleID
(p_TitleID in titles.title_id%type)
return type_title_rec                -- 会报错!! 错误:PLS-00498: 在说明一个类型之前对其进行了非法使用

as

type type_title_rec is record
(
Title titles.title%type,
Price titles.price%type
);
lv_title_rec type_title_rec;
begin
  select title, price into lv_title_rec
  from titles
  where title_id = p_TitleID;
  return (lv_title_rec);
end;

####解决方法####

create or replace function FunGetTitleByTitleID
(p_TitleID in titles.title_id%type)
--return type_title_rec                -- 会报错!! 错误:PLS-00498: 在说明一个类型之前对其进行了非法使用
return titles%rowtype                  -- 使用rowtype解决。
as
type type_title_rec is record
(
Title_id titles.title_id%type,
Title titles.title%type,
Price titles.price%type,
Type titles.type%type
);
lv_title_rec type_title_rec;
begin
  select title_id, title, price,type into lv_title_rec
  from titles
  where title_id = p_TitleID;
  return (lv_title_rec);
end;

####调用方法####

declare
lv_rr titles%rowtype;
begin
lv_rr := FunGetTitleByTitleID(2);
dbms_output.put_line(lv_rr.Title_id);
dbms_output.put_line(lv_rr.Title);
dbms_output.put_line(lv_rr.Price);
dbms_output.put_line(lv_rr.Type);
end;

--创建异常测试表--
create table exp1(
  expid int primary key,
  expname varchar2(12) unique,
  expdate date
);

set serveroutput on;      --打开控制台输出--

declare

lv_errnum_num int;
begin
  insert into exp1 values(1,'Exp1','01-1月-05');
  exception
    when others then
    dbms_output.put_line('错误编号:' ||  sqlcode);
    dbms_output.put_line('错误描述:' ||  sqlerrm);
end;

错误编号:-1

错误描述:ORA-00001: 违反唯一约束条件 (NEWLIFEYHJ.SYS_C002167)

insert into exp1 values(1,'Exp1','01-0月-05');    -- 写成0月

错误编号:-1843
错误描述:ORA-01843: 无效的月份

insert into exp1 values('aaa','exp1','01-2月-05'); --'aaa'

错误编号:-1722
错误描述:ORA-01722: 无效数字

declare

lv_errnum_num int;
begin
insert into exp1 values('aaa','exp1','01-2月-05');
exception
when others then
  dbms_output.put_line('错误编号:' ||  sqlcode);
    dbms_output.put_line('错误描述:' ||  sqlerrm);
--if sqlcode = -1 then
  --dbms_output.put_line('名字不能重复!!');
--end if;
  case sqlcode
  when -1 then
    dbms_output.put_line('名字不能重复!!');
  when -1722 then
    dbms_output.put_line('名字必须是数字!!');
  end case;
end;

declare
lv_errnum_num int;
MyFirstException exception;
pragma exception_init(MyFirstException,-0001);  --绑定异常code
begin
insert into exp1 values(1,'exp1','01-2月-05');
exception
  --when dup_val_on_index then
  when MyFirstException then
    dbms_output.put_line('名字不能重复!!');
end;

declare

DUP_VAL_ON_INDEX2 exception;
pragma exception_init(DUP_VAL_ON_INDEX2,-0001);  --系统自己绑定的不需要自己去绑定了!!
begin
  insert into exp1 values(1,'exp1','01-1月-05');
  exception
  when DUP_VAL_ON_INDEX then                     --这样一样可以捕获的到异常!! 写成DUP_VAL_ON_INDEX2也可以!!
    dbms_output.put_line('DoItYourself!');
end;

-- 自定义异常
declare
lv_TitleCount_num numeric(3) := 0;
lv_NoTitles_exp exception;
lv_MoreTitles_exp exception;
begin
  select count(title_id) into lv_TitleCount_num
  from titles;
  dbms_output.put_line(lv_TitleCount_num);       --测试语句,打印出当前值是多少。--
  if lv_TitleCount_num > 0 then
    Raise lv_MoreTitles_exp;
  elsif lv_TitleCount_num <= 0 then
    Raise lv_NoTitles_exp;
  end if;
exception
  when lv_NoTitles_exp then
    dbms_output.put_line ('No Titles!');
  when lv_MoreTitles_exp then
    dbms_output.put_line ('More Titles!');
end;

##raise_application_error应用##

declare
lv_i_num int;
JDI_M exception;
JDI_L exception;
pragma exception_init( JDI_M, -20001);
pragma exception_init( JDI_L, -20998);
begin
  lv_i_num := 8;
  if lv_i_num > 10 then
    raise_application_error( -20001, 'Too Many!');    --错误编号必须介于-20000和-20999之间
  else
    raise_application_error( -20998, 'Too Little!');  --错误编号必须介于-20000和-20999之间
  end if;
exception
  when JDI_M then
    dbms_output.put_line('TM');
  when JDI_L then
    dbms_output.put_line('TL');
end;

declare
lv_TitleCount_num numeric(3) := 0;
lv_NoTitles_exp exception;
lv_MoreTitles_exp exception;
pragma exception_init(lv_NoTitles_exp,-20001);
pragma exception_init(lv_MoreTitles_exp,-20002);
begin
  select count(title_id) into lv_TitleCount_num
  from titles;
  dbms_output.put_line(lv_TitleCount_num);       --测试语句,打印出当前值是多少。--
  if lv_TitleCount_num > 0 then
    Raise_Application_error(-20002,'书籍太多!');
  elsif lv_TitleCount_num <= 0 then
    Raise_Application_error(-20001,'没有书籍!');
  end if;
--exception                                     --如果没有注释,那么执行打印信息。否则输出Raise_Application_error的定义信息。--
  --when lv_NoTitles_exp then
  --  dbms_output.put_line ('No Titles!');
  --when lv_MoreTitles_exp then
  --  dbms_output.put_line ('More Titles!');
end;

转载地址:http://hjhel.baihongyu.com/

你可能感兴趣的文章
Javascript数组小结
查看>>
我的友情链接
查看>>
2019年学习博文分享
查看>>
用python实现九九乘法表
查看>>
Mindscape WebWorkbench 支持Visual Studio 2012 最新破解
查看>>
大型网站技术架构(四)网站的高性能架构
查看>>
Log4j 1使用教程
查看>>
详解haproxy
查看>>
资深老师给小学生家长的建议
查看>>
MyBatis学习总结(14)——Mybatis使用技巧总结
查看>>
<org manual>翻译--3.5.9 高级特性
查看>>
常用HTML正则表达式
查看>>
Linux lsof命令详解
查看>>
我是如何破解你的WINDOWS密码的 ?(1)
查看>>
SQL Server: Top 10 Secrets of a SQL Server Expert
查看>>
loop循环
查看>>
laravel完美部署与六种解决报错高效方法
查看>>
iscsi多路径客户端的配置
查看>>
Ubuntu启动器快捷方式
查看>>
dhcp在企业网中的应用
查看>>