Oracle的PL/SQL编程前奏之基础技能实战六(包)

                                                                                               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':表示作业立即运行,运行完退出,不会重复运行


猜你喜欢

转载自blog.51cto.com/11218855/2366958