oracle-游标-存储过程-函数-包
Posted 丨逸仙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle-游标-存储过程-函数-包相关的知识,希望对你有一定的参考价值。
一、存储过程 不可以在insert,update,delete中直接使用,可以有return但代表的是退出过程 过程有三种类型:不返回值,可以返回多个值,参数有三种类型,分别如下: in:只输入,不返回结果,默认为in out:只返回结果,不输入,要想取出输出变量的值必须通过pl/sql块的变量取出 in out:可输入,又可返回结果,要想取出输出变量的值必须通过pl/sql块的变量取出 --语法 create or replace procedure 名称(a1 in varchar2,a2 out varchar2,a3 in out int) as begin end; --测试in create or replace procedure getSex1(p_customerName in varchar2) as v_sex varchar2(20); begin select sex into v_sex from customer where customerName=p_customerName; dbms_output.put_line(v_sex); end; --测试out create or replace procedure getSex2(p_customerName in varchar2,p_sex out varchar2) as begin select sex into p_sex from customer where customerName like p_customerName; exception when others then raise_application_error(-20001,‘occur error‘); end; --测试in out create or replace procedure getSex3(p_param1 in out varchar2) as begin select sex into p_param1 from customer where customerName=p_param1; end; --在pl/sql块中执行 declare begin getSex1(‘a1‘); end; --在pl/sql块中执行 declare p_sex varchar2(20); begin getSex2(‘a1‘,p_sex); dbms_output.put_line(p_sex); getSex2(‘a2‘,p_sex); dbms_output.put_line(p_sex); end; declare p_sex varchar2(20); begin p_sex:=‘a1‘; getSex3(p_sex); dbms_output.put_line(p_sex); p_sex:=‘a2‘; getSex3(p_sex); dbms_output.put_line(p_sex); end; 二、函数: 只能返回且必须返回一个结果,可以直接用在insert,update,delele,select中 可以有多个return; 语法: create or replace function 函数名(p1 varchar2) return varchar2 as begin exception end; 实例:根据姓名返回姓别 create or replace function getSex(p_customerName varchar2) return varchar2 as v_sex customer.sex%type; begin select sex into v_sex from customer where customerName=p_customerName; return v_sex; end; 执行函数: 1、在sql(sqlplus) select getSex(customerName),sex from customer; 2、在pl/sql块中 declare v_sex customer.sex%type; begin v_sex:=getsex(‘a1‘); dbms_output.put_line(v_sex); end; 存储过程: 1.声明处没有return,可以返回多个值,用输出变量(out,in out)返回 return代表退出程序,不返回结果. 2.不可以在insert,update,delete,select 中直接使用,只能通过exec中用 函数: 1.声明处有return,只可以返回一个值, return代表返回一个值. 2.可以在insert,update,delete,select 中直接使用. 三、触发器 set serveroutput on; create or replace trigger teacher_trigger after insert or update or delete on customer for each row begin dbms_output.put_line(‘the table data already has been modified....‘); end; 四、游标 declare v_customer customer%rowtype; v_customerName customer.customerName%type; cursor c1(v_customerName varchar2) is select * from customer where customerName like v_customerName; begin v_customerName:=‘&aa‘; open c1(v_customerName); fetch c1 into v_customer; while(c1%found) loop dbms_output.put_line(v_customer.customerName||‘ ‘||v_customer.sex); fetch c1 into v_customer; end loop; end; 五、包 包:包中可以有多个方法,包包括包声明与包主体,包声明中声明的方法名,参数名,类型,个数必须与包主体的方法完全一样。 包声明中声明的变量是全局变量,大家都可以用 --实现包声明 create or replace package my_p as function getReverse(v_name varchar2) return varchar2; procedure teacher_modify_column(teacher_id number,column_name varchar2,column_value1 number); end; create or replace package body my_p as procedure teacher_modify_column(teacher_id number,column_name varchar2,column_value1 number) is v_sql varchar2(200); begin v_sql:=‘update teachers set ‘||column_name||‘ = ‘||column_value1||‘ where teachers.teacher_id = ‘||teacher_id; EXECUTE IMMEDIATE v_sql; end teacher_modify_column; function getReverse(v_name varchar2) return varchar2 as v_title varchar2(200); i int:=1; j int:=0; begin j:=length(v_name); while (j>0) loop v_title:= substr(v_name,i,1)||v_title; i:=i+1; j:=j-1; end loop; return v_title; end; end; create or replace package MyPackage as type c_type is ref cursor; function MyReverse(source varchar2) return varchar2; procedure splitPage(p_sql varchar2,page int,pageSize int,result out c_type,pageCount out int); end; --实现包主体 create or replace package body MyPackage as function MyReverse(source varchar2) return varchar2 as i int; j int; result varchar2(2000):=‘‘; begin j:=length(source); i:=1; while(i<=j) loop result:=substr(source,i,1)||result; i:=i+1; end loop; return result; end; // 查询语句 页数 procedure splitPage(p_sql varchar2,page int,pageSize int,result out c_type,pageCount out int) as v_sql varchar2(500); startPage int; endPage int; v_rowCount int; begin v_sql:=‘select count(*) from (‘||p_sql||‘)‘; dbms_output.put_line(v_sql); execute immediate v_sql into v_rowCount; pageCount:=ceil(v_rowCount/pageSize); if(page=0) then raise_application_error(-20001,‘申请的页面太小‘); end if; if(page>pageCount) then raise_application_error(-20001,‘申请的页面太大‘); end if; startPage:=(page-1)*pageSize; endPage:=page*pageSize; v_sql:=‘select * from (‘||p_sql||‘) where rowNum<=‘||to_char(endPage); v_sql:=v_sql||‘ minus ‘; v_sql:=v_sql||‘select * from (‘||p_sql||‘) where rowNum<=‘||to_char(startPage); dbms_output.put_line(v_sql); open result for v_sql; end; end; --调用包中的方法 select MyPackage.MyReverse(sex) from customer; --在pl/sql块中调用 declare pageCount int; c1 mypackage.c_type; v_customer customer%rowtype; begin mypackage.splitPage(‘select * from customer‘,1,2,c1,pageCount); dbms_output.put_line(‘总页数是‘||pageCount); fetch c1 into v_customer; while(c1%found) loop dbms_output.put_line(v_customer.customername||‘ ‘||v_customer.sex); fetch c1 into v_customer; end loop; close c1; mypackage.splitPage(‘select * from customer‘,2,2,c1,pageCount); fetch c1 into v_customer; while(c1%found) loop dbms_output.put_line(v_customer.customername||‘ ‘||v_customer.sex); fetch c1 into v_customer; end loop; close c1; mypackage.splitPage(‘select * from customer‘,3,2,c1,pageCount); fetch c1 into v_customer; while(c1%found) loop dbms_output.put_line(v_customer.customername||‘ ‘||v_customer.sex); fetch c1 into v_customer; end loop; close c1; mypackage.splitPage(‘select * from customer‘,4,2,c1,pageCount); fetch c1 into v_customer; while(c1%found) loop dbms_output.put_line(v_customer.customername||‘ ‘||v_customer.sex); fetch c1 into v_customer; end loop; close c1; end;
以上是关于oracle-游标-存储过程-函数-包的主要内容,如果未能解决你的问题,请参考以下文章
Oracle03——游标异常存储过程存储函数触发器和Java代码访问Oracle对象