Oracle的PL/SQL编程前奏之基础技能实战六
一>编写包规范及包体,包体中包含存储过程,函数的实现。
create or replace package emp_action_pkg is v_deptno number(3):=20; -----定义一个增加员工的过程 procedure newdept( p_deptno dept.deptno%Type,-----部门编号 p_dname dept.dname%type, -----部门名称 p_loc dept.loc%type -----位置 ); function getraisedsalary(p_empno emp.empno%type) return number; end;
总结:1>%type定义了与dept表中deptno,dname,loc列相同的类型。
2>定义了包规范。
create or replace package body emp_action_pkg is ----公开,实现包规范中定义的newdept过程 procedure newdept( p_deptno dept.deptno%Type,-----部门编号 p_dname dept.dname%type, -----部门名称 p_loc dept.loc%type -----位置 ) as v_deptcount number;-----保存是否存在员工编号 begin select count(*) into v_deptcount from dept where deptno=p_deptno;---查询在dept表中是否存在部门编号 if v_deptcount>0 then raise_application_error('-20002','出现了相同的员工记录'); end if; insert into dept(deptno,dname,loc) values(p_deptno,p_dname,p_loc);---插入记录 end; ----公开,实现包规范中定义的getraisedsalary函数 function getraisedsalary(p_empno emp.empno%type) return number is v_job emp.job%type;---职位变量 v_sal emp.sal%type;---薪资变量 v_salaryratio number(10,2);---调薪比例 begin select job,sal into v_job,v_sal from emp where empno=p_empno; case v_job when '职员' then v_salaryratio:=1.09; when '销售人员' then v_salaryratio:=1.11; when '经理' then v_salaryratio:=1.18; else v_salaryratio:=1; end case; if v_salaryratio<>1 then ----如果有调薪的可能 return round(v_sal*v_salaryratio,2);----返回调薪后的薪资 else return v_sal; end if; ----否则不返回薪资 exception when no_data_found then return 0; -----如果没有找到员工记录,返回0 end;
---私有,该函数在包规范中并不存在,只能在包体内被引用 function checkdeptno(p_deptno dept.deptno%type) return number as v_counter number(2); begin select count(*) into v_counter from dept where deptno=p_deptno; return v_counter; end; end;
总结:1>对赋值后的变量进行case判断:
case v_job when '职员' then v_salaryratio:=1.09; when '销售人员' then v_salaryratio:=1.11; when '经理' then v_salaryratio:=1.18; else v_salaryratio:=1; end case;
2>编写包体实现包规范
3>checkdeptno在包规范中不存在,只能在包体内被引用。
begin emp_action_pkg.v_deptno:=30; dbms_output.put_line(emp_action_pkg.getraisedsalary(7369)); end; begin emp_action_pkg.v_deptno:=50; emp_action_pkg.newdept(45,'采纳部','佛山'); end; begin dbms_output.put_line(emp_action_pkg.v_deptno); end;
总结:1>编写三个匿名块调用包组件。
二>使用DBMS_JOB创建作业(用于分析数据表)。
1>运用dbms_job包创建作业作业,作业执行的存储过程为analyze_object DECLARE v_jobno NUMBER; BEGIN DBMS_JOB.submit (v_jobno, --作业编号 --作业执行的存储过程 'DBMS_DDL.analyze_object(''TABLE'',''SCOTT'',''EMP'',''COMPUTE'');', --以sysdate作为下一次执行的日期 SYSDATE, --Interval属性执行的时间间隔,表示24小时。 'SYSDATE+1' ); DBMS_OUTPUT.put_line('获取的作业编号为:'||v_jobno); --输出作业编号 COMMIT; END;
2>查询创建的作业
select job,next_date,next_sec,interval,what from user_jobs;
总结:
A>interval参数是varchar2字符串类型,不是一个日期或天或分钟的数字,可以传递想传递的字符串
‘sysdate+1’:表示下一天的当前时间
'trunc(sysdate)+1':表示下一天的午时,即12点
'trunc(sysdate)+17/24':在每天下午5点运行
'null':表示作业立即运行,运行完退出,不会重复运行