------------------------2013-5-18------------------------
异常raise_application_error:错误编号必须介于-20000和-20999之间错误消息的长度可长达2048个字节。游标类型
静态游标 隐式游标 sql%found sql%rowcount 显式游标 cur_xxx%foundref游标游标属性
%notfound %found %rowcount %isopen控制显示游标 open fetch close循环游标 显式游标
隐式打开游标 自动从活动集获取行 在处理完所有行时关闭游标优点 简化代码的编写游标变量的类型:强游标,弱游标。
游标管理 限制
不能在程序包中声明游标变量 远程子程序不能接受游标变量的值 不能使用比较操作符对游标变量进行相等或不相等测试 不能将空值赋予游标变量 表不能存储游标变量的值 -- 包create or replace package pkg_Testistype 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_Testis 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需要重新打开输出。-- 包函数调用
declarelv_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;-- 包过程调用
declarelv_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解决。astype 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;####调用方法####
declarelv_rr titles%rowtype;beginlv_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');exceptionwhen 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; declarelv_errnum_num int;MyFirstException exception;pragma exception_init(MyFirstException,-0001); --绑定异常codebegin 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; -- 自定义异常declarelv_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; declarelv_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;