日期:2014-05-16 浏览次数:20436 次
--子程序 /* 子程序是被命名的PL/SQL块,可以带参数,多次被调用,模块化 过程&&函数 过程:执行特定操作 函数:返回特定数据 定义: CREATE [OR REPLACE] PROCEDURE procedure_name(argument [mode] datatype...) IS|AS --这里可以声明一些变量,相当于declare块,不过没有declare关键字 BEGIN statement... END; -------******------- procedure_name 过程名 argument 参数名 mode 参数类型, IN 输入参数 || OUT 输出参数 ||IN OUT . 默认是输入参数 datatype 参数类型 ,不需要指定长度 */ --不带参数 CREATE OR REPLACE PROCEDURE p_time IS BEGIN dbms_output.put_line(sysdate); END; --调用 call p_time(); --默认IN型参数 CREATE OR REPLACE PROCEDURE emp_1(num int) AS v_name emp.ename%type; v_deptno emp.deptno%type; BEGIN IF num<10000 THEN--根据传入的参数,是否执行查询 select ename,deptno into v_name,v_deptno from emp where emp.empno=num; dbms_output.put_line(v_name||'--'||v_deptno); ELSE dbms_output.put_line('too big'); END IF; END; --调用 BEGIN emp_1(77880); END; --明确定义参数模式 /* IN read-only :pass values into 相当于一个常量 OUT write-only :pass values back 相当于一个变量 IN OUT read/write */ CREATE OR REPLACE PROCEDURE emp_count_1(v_deptid IN int,v_count OUT int)--一个IN,一个OUT IS BEGIN select count(emp.empno) into v_count from emp where emp.deptno=v_deptid; dbms_output.put_line(v_count); END; --调用 DECLARE v_count int; BEGIN --传递OUT类型的参数是传递一个类型相符的变量,因为out的类型的是要作为输出的,所以需要具体的变量来存放 emp_count_1(10,v_count); --传递参数默认按定义顺序,但也可以如下按照参数名称 emp_count_1(v_count=>v_count,v_deptid => 10); --当然也可以两种方式混合使用 emp_count_1(10,v_count => v_count); END; --感觉out的参数很麻烦的,还不如在过程内直接定义一个变量 CREATE OR REPLACE PROCEDURE emp_count_2(v_deptid IN INT) IS v_count int; BEGIN select count(emp.empno) into v_count from emp where emp.deptno=v_deptid; dbms_output.put_line(v_count); END; --调用 BEGIN emp_count_2(10); END; --过程调用过程 CREATE OR REPLACE PROCEDURE p_main IS BEGIN--调用上面定义的两个过程 p_time(); emp_count_2(10); END; --调用 BEGIN p_main(); END; --函数 /* 有返回值,其它的和过程差不多 CREATE [OR REPLACE] FUNCTION function_name(argument [mode] datatype...) RETURN datatype --返回类型必须 IS|AS [variable datatype...] BEGIN statement... Pl/SQL块中必须要有一条return语句 END; */ -- CREATE OR REPLACE FUNCTION get_name(u_id IN int) RETURN varchar2 AS v_name emp.ename%type; BEGIN select ename into v_name from emp where emp.empno=u_id; RETURN v_name; END; --调用 DECLARE v_name emp.ename%type; v_job emp.job%type; BEGIN v_name :=get_name(7788);--直接给变量赋值 select job into v_job from emp where ename=get_name(7788) and rownum<2;--在查询语句中调用 dbms_output.put_line(v_name); END; --返回record CREATE OR REPLACE FUNCTION get_record(pno in number) RETURN emp%rowtype IS v_record emp%rowtype; BEGIN select * into v_record from emp where empno=pno; return v_record; END; -- DECLARE v_record emp%rowtype; BEGIN v_record := get_record(7788); dbms_output.put_line(v_record.ename||'--'||v_record.job); END; --如果一个函数没有参数,那么调用他的时候可以不用加() --exp CREATE OR REPLACE FUNCTION get_num(v_id in int) RETURN INT IS CURSOR v_cs is select count(empno) tt,max(empno) mx from emp where emp.deptno=v_id group by deptno; v_num v_cs%rowtype; BEGIN OPEN v_cs; FETCH v_cs into v_num; dbms_output.put_line(v_num.tt||'--'||v_num.mx); close v_cs; RETURN v_num.tt; END; -- select get_num(10) from dual; --综合例子 --统计emp表中每个部门的人员 DECLARE --声明一个嵌套表用来存放要查询的部门编号 TYPE v_array IS VARRAY(5) OF INT; v_arr v_array; --声明一个嵌套表用来存放每一个部门的员工名字 TYPE v_list_type IS TABLE OF VARCHAR2(30); v_list v_list_type := v_list_type(); --声明一个函数 根据部门查询统计该部门的员工总数和员工名字 FUNCTION get_num(v_dpno IN INT) RETURN v_list_type IS v_num INT; v_i int :=1; v_name varchar2(30); v_names v_list_type := v_list_type(); TYPE v_cs_type IS REF CURSOR; v_cs v_cs_type; BEGIN --统计员工总数 select count(empno) into v_num from emp where emp.deptno= v_dpno; dbms_output.put_line('编号是:'||v_dpno||'的部门的员工数是:'||v_num); --查询该部门员工名字 OPEN v_cs FOR select