10开发子程序:过程和函数
过程:执行特定操作
函数:用于返回特定数值
10.1过程
语法:
- create [or replace] procedure procedure_name(argument1 [model] datatype1,arguement2 [mode2],...)
- is [as]
- pl/sql block;
1.建立过程:不带任何参数
- create or replace procecdure out_time
- is
- begin
- dbms_output.put_line(systimestemp);
- end;
2.调用过程
- set serveroutput on
- exec out_time
- set serveroutput on
- call out_time();
3.建立过程:带有IN参数
- create or replace procedure add_employee
- (eno number,name varchar2,sal number,job varchar2 default 'clerk',dno number)
- is
- e_integrity exception;
- pragma exception_init(e_integrity,-2291);
- begin
- insert into imp(empno,ename,sal,job,deptno) values(eno,name,sal,job,dno);
- exception
- when dup_val_on_index then
- raise_application_error(-20000,'雇员号不能重复');
- when e_integrity then
- raise_application_error(-20001,'部门不存在');
- end;
- exec add_employee(1111,'clark',2000,'manager',10) ;
4.建立过程:带有OUT参数
- create or replace procedure query_employee
- (eno number,name out varchar2,salary out number)
- is
- begin
- select ename,sal into name,salary from emp where empno=eno;
- exception
- when no_date_found then ---no_date_found表示如何select into没有数据就放回true
- raise_application_error(-20000,'该雇员不存在');
- end;
当在应用程序中调用该过程时,必须要定义变量接受输出参数的数据
- sql>var name varchar2(10)
- var salary number
- exec query_employee(7788,:name,:salary)
- print name salary
5.建立过程:带有IN OUT参数(输入输出参数)
- create or replace procedure compute
- (num1 in out number,num2 in out number)
- is
- v1 number;
- v2 number;
- begin
- v1:num1/num2;
- v2:mod(num1,num2);
- num1:=v1;
- num2:=v2;
- end;
- sql>var n1 number
- var n2 number
- exec :n1:=100
- exec :n2:=30
- exec ecmpute(:n1,:n2)
- print n1 n2
6.为参数传递变量和数据
位置传递,名称传递,组合传递三种
1.位置传递:在调用子程序时按照参数定义的顺序为参数指定相应的变量或数值
- exec add_dept(40,'sales','new york');
- exec add_dept(10);
2.名称传递:在调用子程序时指定参数名,并使用关联符号=>为其提供相应的数值或变量
- exec add_dept(dname=>'sales',dno=>50);
- exec add_dept(dno=>30);
3.组合传递:同时使用位置传递和名称传递
- exec add_dept(50,loc=>'new york');
- exec add_dept(60,dname=>'sales',loc=>'new york');
7.查看过程原代码
oracle会将过程名,源代码以及其执行代码存放到数据字典中.执行时直接按照其执行代码执行
可查询数据字典(user_source)
- select text from user_source where name='add_dept';
删除过程
- drop procedure add_dept;
10.2函数
用于返回特定函数
语法:
- create [or replace] function function_name
- (argument1 [mode1] datatype1,
- argument2 [mode2] datatype2,
- .....)
- return datatype --函数头部必须要带有RETURN子句,至少要包含一条RETURN语句
- is|as pl/sql block;
1.建立函数:比带任何参数
- create or replace function get_user
- return varchar2
- is
- v_user varchar2(100);
- begin
- select username into v_user from user_users;
- return v_user;
- end;
2.使用变量接受函数返回值
- sql>var v1 varchar2(100)
- exec :v1:=get_user
- print v1
- 在SQL语句中直接调用函数
- select get_user from dual;
- 使用DBMS_OUTPUT调用函数
- set serveroutput on
- exec dbms_output.put_line('当前数据库用户:'||ger_user)
3.建立函数:带有IN参数
- create or replace function get_sal(name in varchar2)
- return number
- as
- v_sal emp.sal%type;
- begin
- select sal into v_sal from emp where upper(ename)=upper(name);
- return v_sal;
- exception
- when no_data_found then
- raise_application_error(-20000,'该雇员不存在');
- end;
4.建立函数:带有out参数
- create or replace function get_info(name varchar2,title out varchar2)
- return varchar2
- as
- deptname dept.dname%type;
- begin
- select a.job,b.dname into title,deptname from emp a,dept b and a.deptno=b.deptno
- and upper(a.ename)=upper(name);
- return deptname
- exception
- when no_data_found then
- raise_application_error(-20000,'该雇员不存在');
- end;
- sql>var job varchar2(20)
- var dname varchar2(20)
- exec :dname:=get_info('scott',:job)
- print danme job
5.建立函数:带有IN OUT参数
- create or replace function result(num1 number,num2 in out number)
- return number
- as
- v_result number(6);
- v_remainder number;
- begin
- v_result:=num1/num2;
- v_remainder:=mod(num1,num2);
- num2:=v_remainder;
- return v_result;
- exception
- when zero_divide then
- raise_application_error(-20000,'不能除0');
- end;
- sql>var result1 number
- var result2 number
- exec :result2:=30
- exec :result1:=result(100,:result2)
- print result result2
6.函数调用限制
SQL语句中只能调用存储函数(服务器端),而不能调用客户端的函数
SQL只能调用带有输入参数,不能带有输出,输入输出函数
SQL不能使用PL/SQL的特有数据类型(boolean,table,record等)
SQL语句中调用的函数不能包含INSERT,UPDATE和DELETE语句
7.查看函数院源代码
oracle会将函数名及其源代码信息存放到数据字典中user_source
set pagesize 40
select text from user_source where name='result';
8.删除函数
drop function result;
10.3管理子程序
1.列出当前用户的子程序
数据字典视图USER_OBJECTS用于显示当前用户所包含的所有对象.(表,视图,索引,过程,函数,包
- sql>col object_name format a20
- select object_name,created,status from user_objects where object_type in ('procedure','function')
2.列出子程序源代码
- select text from user_source where name='raise_salsry';
3.列出子程序编译错误
使用SHOW ERRORS命令确定错误原因和位置
- show errors procedure raise_salary
使用数据字典视图USER_ERRORS确定错误原因和位置
- col text format a50
- select line||'/'||position as "line/col",text error from user_errors where name='raise_salary';
4.列出对象依赖关系
使用数据字典视图USER_DEPENDENCIES确定直接依赖关系
- select name,type from user_dependencies where referenced_name='emp';
使用工具视图DEPTREE和IDEPTREE确定直接依赖和间接依赖关系
先运行SQL脚本UTLDTREE.SQL来建立这两个视图和过程DEPTREE_FILL,然后调用DEPTREE_FILL填充这两个视图
- sql>@%oracle_home%\rdbms\admin\utldtree
- exec deptree_fill('TABLE','scott','emp')
执行后会将直接或间接依赖于SCOTT.EMP表的所有对象填充到视图DEPTREE和IDEPTREE中.
- select nested_level,name,type from deptree;
- select * from ideptree
5.重新编译子程序
当修改了被引用对象的结构时,就会将相关依赖对象转变为无效(INVALID)状态。
- alter table emp add remark varchar2(10);
- select object_name,object_type from user_objects where status='invalid';
为了避免子程序的运行错误,应该重新编译这些存储对象
- alter procedure add_employee compile;
- alter view dept10 compile;
- alter function get_info compile;
感谢April-Myhou!