Oralce 存储过程 和 函数




--____________________________________子程序(过程和函数)____________________________________________

--1.创建过程 :无参数
create or replace procedure pro_del_dup_rec
as [is]
begin
delete teb_test a where a.rowid=(select max(rowid) from tb_test b where a.a=b.a and a.b=b.b);
end;


--2.带有IN的参数的过程 (输入参数)
create or replace procedure pro_transit_station
(
v_start_station tb_station.station_name%type, --定义一个变量用于保存起点站
v_end_station tb_station.station_name%type; --定义一个变量用于保存终点站
V_line_name tb_station.line_name%type:='536' --定义变量把保存公交的车次
)
as
v_start_forder tb_station.forder%type; --定义变量用户保存起点站的序号
v_end_forder tb_station.forder%type; --定义变量用于保存终点站的序号
v_station_line varchar2(100); --定义变量用于保存起点到终点的线路
type Station_name_table_type is table of tb_station.station_name%type; --自定义一个索引表 用户保存一组车站的名字
v_station_name_table Station_name_table_type; --自定义类型的变量
begin

--查询出起点和终点站的的序号 分别保存到变量中
select fouder into v_start_forder from tb_station where line_name=v_line_name and station_name=v_start_station;
select forder into v_end_forder from tb_station where line_name=v_line_name and station_name=v_end_station;

--判断 如果终点站的序号必起点站的序号大 就说明是 去的路上
if v_start_forder<=v_end_forder
select staion_name bulk collect into v_station_name_table from tb_station
where line_name=v_line_name and forder>=v_start_forder and forder<=v_end_forder order by forder ;
--否则 说明是回来的路上
else
select station_name bulk collect into v_station_name_table from tb_sataion
where line_name=v_line_name and forder>=v_end_forder and forder<=v_start_forder order by forder desc;
END if;
--输出 起点站和终点站的 开头 部分;
DBMS_OUTPUT.put_line(v_line_name||'公交车【'||v_start_name||'->'||v_end_station||'】站的公交路线:');
--循环遍历表中的数据
for i in v_station_name_table.first..v_station_name_table.last
LOOP
-- 累加 途中车站的名称
v_station_line:=v_station_line||v_station_name_table(i)||'->';
end LOOP;
--去掉最后多的一个 '->'
v_station_line=sbustr(v_station_line,0,length(v_station_line)-2);
--输出途中的车站名称
DBMS_output.put_line(v_station_line);
Exception
when no_data_found then
DBMS_OUTPUT.put_line('请输入正确的公交车次路线!');
END;

--调用此过程 (除了具有默认值的参数外,其他参数必须提供数值)
Call pro_transit_station('常青路','武胜路','536'); --没有使用默认值
--或者
Call pro_transit_station('常青路','武胜路'); --使用了默认值


--3.带有Out的过程 (有输出参数)
--示例1
create or replace procedure proc_query_em
(
param_empno numner,
param_ename out varchar2(20),
param_salary out number
)
as
begin
select ename,salary into param_ename,param_salary from emp where empno=param_empno;
Exception
when no_data_found then
raise_application_error(-2000,'该雇员不存在!');
END;

--调用带有out 参数的的过程 必须定义变量接受输出参数的数据
declare
v_empno emp.empno%type:=7788;
v_ename emp.ename%type;
v-salary emp.salary%type;
Begin
proc_query_emp(v_empno,v_ename,v_salary);
DBMS_output.put_Line(v_ename||' '||v_salary);


--4.创建带有 in out 的参数 (in out 是值输入输出参数)
--示例1
create or replace procedure pro_eompute
(
param_num1 in out number,
param_num2 in out number
)
as
v1 number;
v2 number;
begin
v1:=param_num1/param_num2;
v2:=MOD(param_num1,param_num2);
param_num1:=v1;
param_num2:=v2;
END;
--调用 in out 过程 必须提供两个变量临时赋值
declare
v_num1 number(2):=10;
v_num2 number(2):=3
begin
proc_compute(v_num1,v_num2);
DBMS_output.put_line(v_num1);
DBMS_outPut.put_line(v_num2);
end;

--5.过程中的参数 使用 “按值传递” 和 “位置传递 ” 和 “组合传递”
--1 定义过程
delcare or replace procedure proc_add_dept
(
param_deptno number,
param_dname varchar2(20),
param_loc varchar2(20):=null
)
as
begin
insert into dept values(param_deptno,param_dname,param_loc);
Exception
when Dup_val_on_index then
raise_application_error(-2000,'部门编号不能重复');
END;
--按值传递
call proc_add_dept(60,'manager','beijing'); --没有使用默认值
--或者
call proc_add_dept(70,'product'); --使用默认值

--按名称传递
call proc_add_dept(param_dept=>80;param_dname=>'purchase',param_loc=>'wuhan');

--按组合传递 (第一个参数要按位置传递)
call proc_add_dept(90,'admin',param_loc=>'wuhan');





--__________________________________________函数(用于返回指定的值)_____________________________________

--语法
create [or replace] function function_name --function_name :函数的名称
(
argument1 [model1] datatype1; -- 函数的参数: 在指定函数参数类型时候,不能指定长度
argument2 [model2] datatype2;
....

)
return datatype --指定函数的返回类型 函数必须要有return
is|AS --is|As 用于开始 一个 PL/SQL 语句块
声明部分
begin
执行部分 --在函数体内至少包含一条return 语句
exception
异常部分
END;

--示例1
create or replace function fun_get_user
return varchar2
as
v_user varchar2(100);
begin
select username into v_user from tb_users;
return v_user;
end;
--调用
declare
v_user varchar2(100);
begin
v_user:=fun_get_user;
DBMS_outpur.put_line('当前用户是'||v_user);
end;
--或者 直接调用
select fun_get_user 当前用户 from dual;

--1.创建带有 in 参数(输入)
create or replace function fun_get_sal
(parm_name varchar2) -- 定义了一个输入参数
return number
as
v_sal emp%type;
begin
select sal into v_sal from emp where upper(param_name)=upper(sname);

Exception
when no_data_found then
raise_application_error(-2000,'该雇员不存在!');
END;
--调用
declare
v_ename emp.ename%type:=&ename;
begin
DBMS_output.put_line(fun_get_sal(v_ename));
end;


--2.带有 out 参数的 函数
declare or replace function fun_get_emp_info
(
param_ename varchar2, --输入参数
param_dname out varchar2 --输出参数
)
return varchar2
as
v_ejob emp.job%type; --返回的变量
begin
select a.job,b.dname into v_job,param_dname from emp a,dept b where a.deptno=b.deptno and upper(a.ename) =upper(param_ename);
return --异常
when no_data_found then
raise_application_erroe(-2000,'该员工不存在!');
END;

--调用
declare
v_ename varchar2(20):=&v_ename;
v_dname varchar(20);
v_ejob varchar2(20);
begin
v_ejob:=fun_get_emp_info(v_ename,v_dname);
DBMS_output.put_line('员工名称'||v_ename);
DBMS_output.put_line('部门名称'||v_dname);
DBMS_output.put_line('员工岗位'||v_ejob);
End;

--3.带有in out 参数的函数
create or replace function fun_compute
(
param_num1 number,
param_num2 in out number ---定义 in out 参数
)
return number
as
v1 number; --定义返回两个数相除的 结果
begin
v1:=param_num1/param_num2;
param_num2:=MOD(param_num1,param_num2); --两数相余 结果 重新赋值给param_num2;
return v1;
ENd;

--调用的时候
declare
v_num1 number(2):=10;
v_num2 number(2):=3;
v_result number(2);
begin
v_resultL:=fun_compute(v_num1,v_num2);
DBMS_output.put_line('余数'||v_num2);
DBMS_output.put_line('商是'||v_result);
End;


--4。过程和函数的 选用
过程: 返回多个值 或不返回值时候
函数: 返回一个值


--5.查看子程序的源码
--查看 函数 fun_computer 的源码
select text from user_source where name=upper('fun_compute');


--6.查看当前用户所包含的所有过程和函数 (User_objects)
col object_name format a20
select object_name 对象名称,created 创建时间,status 状态(valid 有效,invalid 没效) from user_objects where object_type in ('function','procedure');

--7.列出子程序的编译错误 (show error)
create or replace procedure raise_salary -- raise_salary : 对象依赖
(
param_empno number,
param_increase number
)
as
begin
-- emp 是这个 raise_salary 过程的 :引用对象
update emp set sal=sal+param_increase where empno=param_empno -- (故意少了一个结束 " ;" 符号)
end;

--使用 show error 确定错误的位置和原因
show error procedure raise_salary; -- raise_salary 是一个过程的名称

--8.列出对象的依赖关系(user_dependencies) (创建的过程名和函数 :叫 对象依赖, 过程和函数中涉及的表名 :引用对象)

--查询引用对象为 'emp' 的所有 对象依赖 包括 函数 过程 视图
select name,type from user_dependencies a where a.referenced_name='emp' ;


--9.重新编译子程序 (当我们修改了 引用对象(emp..)的结果后 所有的函数 过程 都会无效)
--当函数中没有引用被修改的列时 :经过 PL/SQL 的自动重新编译(即惰性编译)后,就可以正常使用 否则 失败
--此时就要手动重新编译(compile) (函数和过程)
alter procedure pro_query_emp comPile; --这样就可以 正常使用了


--10.删除子程序 (如果不在需要 子程序 (函数 和过程))
--删除 过程
drop procedure pro_query_emp;
--删除 函数
drop function fun_get_sal;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值