oracle 函数,过程,程序包

本文介绍PL/SQL中的子程序(包括过程和函数)及程序包的基础知识。涵盖子程序的创建、参数传递、权限管理、删除等内容,并详细解释了函数与过程的区别。此外,还介绍了程序包的概念、组成部分及其使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

--子程序和程序包

--author:shine
--一。子程序:指的是已经命名的pl/sql块。包括函数和存储过程。
--1.过程
--1)初识
--exp:1.1.1
create or replace procedure
  pro_find_emp(emp_no emp.empno%type) --传入或传出的参数,和外界联系
as
  empname emp.ename%type;  --local局部参数,只在内部使用
begin
  select ename into empname from emp where empno = emp_no;
  dbms_output.put_line(empname);
  exception
    when no_data_found then
      dbms_output.put_line('没找到');
end;

--测试
begin
  pro_find_emp(7369);
end;

--2)过程的参数模式(有in,out,in out)
--exp:1.1.2:in参数
create or replace procedure
  pro_find_emp(e_name in emp.ename%type) --带in的参数(不写时默认为in)
as
  emp_row emp%rowtype;
  type emp_cur_type is ref cursor;
  emp_cur emp_cur_type;
begin
  open emp_cur for 'select * from emp where ename like :1'
  using e_name;
    loop
      fetch emp_cur into emp_row;
      exit when emp_cur%notfound;
      dbms_output.put_line('编号:'||emp_row.empno||'姓名:'||emp_row.ename);
    end loop;
  close emp_cur;
end;

--测试
begin
  pro_find_emp('S%');
end;

--exp:1.1.3:out参数
create or replace procedure
  pro_emp_sal(emp_no in emp.empno%type,emp_test out varchar2) --传入或传出的参数类型不能带长度如:varchar2(10)
as
  emp_sal number(5); --局部参数类型必须带长度
begin
  select sal into emp_sal from emp where empno = emp_no;
  case
    when emp_sal >= 2000 then emp_test := '高工资';
    when emp_sal >=1000 and emp_sal < 2000 then emp_test := '还可以';
    else emp_test :='没戏';
  end case;
end

--测试
declare
  emp_test varchar2(1000);
begin
  pro_emp_sal(7566,emp_test);
  dbms_output.put_line(emp_test);
end;

--exp:1.1.4:in out 参数
create or replace procedure
  pro_emp_transform(num1 in out int,num2 in out int)
as
  temp int;
begin
  temp := num1;
  num1 := num2;
  num2 := temp;
end;

--测试
declare
  num1 int := &num1;
  num2 int := &num2;
begin
  dbms_output.put_line('测试前:num1='||num1||' num2='||num2);
  pro_emp_transform(num1,num2);
  dbms_output.put_line('测试后:num1='||num1||' num2='||num2);
end;

--3)使用过程的原始权限是system和创建过程的用户,要让别人使用就得分权限
grant execute on pro_find_emp to shine;--把执行pro_find_emp的权限分给shine用户

--4)删除过程
drop procedure pro_find_emp;

--2.函数:必须要有返回值,且只能有一个。
--a.函数只能带in参数,不能带in out ,out参数
--b.函数形式参数和返回值类型只能是数据库类型,不能是pl/sql类型如:boolean..
--1)初识:
--exp:1.2.1
create or replace function fun_hello
return varchar2 as
begin
  return 'helloword';
end;

--测试
select fun_hello from dual;

--2)带参数的函数
--exp:1.2.2
create or replace function
  total(num1 in number,num2 in number)
return number as  --从样子上看就比procedure多了个return;
  t_otal number(4) := 10;
begin
  t_otal := num1 + num2;
  if t_otal > 10 then
    dbms_output.put_line(num1||'加'||num2||'的和大于10');
  end if;
  return t_otal;
end;

--测试
select total(&num1,&num2) from dual; --函数不能通过exeucte单独执行,只能通过sql块,和表达式运用。

--3)函数授权
grant execute on total to shine;

--4)删除函数
drop function total;

--稍微总结哈:
--1)过程是重量级的,主要用于执行复杂的更新操作,作为pl/sql块单独执行。
--2)函数是轻量级的,主要用于执行查询操作或计算,转换..,作为表达式的一部分到处用。

--3.自主事务处理
--exp 1.3.1:
create or replace procedure p2
as
  a varchar2(50);
begin
  select ename into a
  from emp where empno = 7369;
  dbms_output.put_line(a);
  rollback;
end;
 
create or replace procedure p1
as
  b varchar2(50);
begin
  update emp set ename='shine'
  where empno = 7369;
  p2();
  select ename into b
  from emp where empno=7369;
  dbms_output.put_line(b);
end;

--测试
begin
  p1();
end;

--结果为:shine smith
--这说明p2中的rollback把p1中的update 回滚了
--上例中,p2的操作影响到p1,为了使每一个过程都能自主处理.有了自主事务处理,pragma autonomous_transaction;
--exp 1.3.2:
create or replace procedure p2
as
  a varchar2(50);
  pragma autonomous_transaction;  --加了自主事务处理
begin
  select ename into a
  from emp where empno = 7369;
  dbms_output.put_line(a);
  rollback;
end;
 
create or replace procedure p1
as
  b varchar2(50);
begin
  update emp set ename='shine'
  where empno = 7369;
  p2();
  select ename into b
  from emp where empno=7369;
  dbms_output.put_line(b);
end;
--结果:smith shine
--说明p2中的rollback 没有回滚p1中的update;

--二、程序包:顾名思义把很多子程序(函数,过程)包在一起、(感觉就像java类一样)
--程序包包括两部分:包规范,包主题
--1、包规范:(就像java中的接口一样,只定义方法不实现,并且在其中定义的方法或属性都是public static)
--exp:2.1.1
create or replace package pack_test as
  procedure pro_emp_findname (emp_no emp.empno%type);
  function fun_emp_findsal(emp_no int) return number;
  username constant varchar(10):='shine';
end pack_test;

--2. 包主体:(要实现接口啦)
create or replace package body pack_test as
  procedure pro_emp_findname (emp_no emp.empno%type) as
  e_name emp.ename%type;
  begin
    select ename into e_name from emp where empno = emp_no;
    dbms_output.put_line('编号:'||emp_no||'名字:'||e_name);
  end;
   
  function fun_emp_findsal(emp_no int) return number as
  e_sal number(4);
  begin
    select sal into e_sal from emp where empno = emp_no;
    return e_sal;
  end;
 
end pack_test;

--测试
select pack_test.fun_emp_findsal(7369) from dual;

begin
  pack_test.pro_emp_findname(7369);
  dbms_output.put_line(pack_test.username);
end;

--3.程序包中的游标(必须要有return)
create or replace package pack_test2 as
  cursor emp_cur(e_name emp.ename%type) return emp%rowtype;
  procedure show_emp(e_name emp.ename%type);
end pack_test2;

create or replace package body pack_test2 as
    cursor emp_cur(e_name emp.ename%type) return emp%rowtype is
    select * from emp where ename like '%'||e_name||'%';
   
    procedure show_emp(e_name emp.ename%type) as
    emp_row emp%rowtype;
    begin
      open emp_cur(e_name);
        loop
          fetch emp_cur into emp_row;
          exit when emp_cur%notfound;
          dbms_output.put_line('编号:'||emp_row.empno||'名字:'||emp_row.ename);
        end loop;
      close emp_cur;
    end;
end pack_test2;

--测试
begin
pack_test2.show_emp('S');
end;


--4.查看包代码
select line,text from user_source
where name='PACK_TEST2';
--5.查看包规范
desc pack_test2;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值