Oracle SQL 学习笔记24 - Oracle 预定义的package

Oracle Server 提供了一些预定义的包,扩展了数据库的功能,例如DBMS_OUTPUT最开始用于开发诊断PS/SQL程序。

DBMS_ALERT

DBMS_LOCK

EXEC  dbms_lock.SLEEP(5);

DBMS_SESSION

DBMS_OUTPUT

DBMS_OUTPUT 如何工作

使用DBMS_OUTPUT可以从子程序和trigger中发送信息。

PUT和PUT_LINE输出字符串到buffer,GET_LINE 和 GET_LINES 读取buffer到变量。但是默认情况下,buffer中的信息并不会显示出来,需要在程序开始处 注明SET SERVEROUTPUT ON。更进一步,SET SERVEROUTPUT ON size n 可以规定buffer的大小,默认值为2,000,最大值为 1,000,000 (1 million字符)。

对应代码执行完成之后,才会发送信息。

UTL_FILE

UTL_FILE 用于和操作系统进行文件交互。通过CREATE DIRECTORY 创建目录对象,也可以通过utl_file_dir指定访问目录。


UTL_FILE.JPG

UTL_FILE 读写流程

READ_WRITE.JPG

UTL_FILE 异常

使用UTL_FILE需要处理许多异常:

  • INVALID_PATH
  • INVALID_MODE
  • INVALID_FILEHANDLE
  • INVALID_OPEARATION
  • READ_ERROR
  • WRITE_ERROR
  • INVALID_ERROR
  • NO_DATA_FOUND
  • VALUE_ERROR

FOPEN 和 IS_OPEN 函数的参数

FUNCTION  FOPEN  (location  IN  VARCHAR2
                  filename  IN  VARCHAR2
                  open_mode  IN  VARCHAR2)
RETURN  UTL_FILE.FILE_TYPE;
FUNCTION  IS_OPEN(file  IN  FILE_TYPE)
RETURN  BOOLEAN;
  • 实例1
CREATE  PROCEDURE  read_file(dir  VARCHAR2,  filename  VARCHAR2)  IS  
  file UTL_FILE.FILE_TYPE;
...
BEGIN
  ...
  IF  NOT  UTL_FILE.IS_OPEN(file)  THEN
    file  :=  UTL_FILE.FOPEN(dir,  filename,  'R');
  END  IF;
END  read_file;
  • 实例2
CREATE  OR  REPLACE  PROCEDURE  sal_status(dir  IN  VARCHAR2,  filename  IN  VARCHAR2)  IS  
  file  UTL_FILE.FILE_TYPE;
  CURSOR  empc  IS
    SELECT  last_name,  salary,  department_id
    FROM  employees  ORDER  BY  department_id;
  newdeptno  employees.department_id%TYPE;
  olddeptno  employees.department_id%TYPE  :=  0;
BEGIN
  file  :=  UTL_FILE.FOPEN(dir,  filename,  'w');
  UTL_FILE.PUT_LINE(file,  'REPORT:  GENERATED  ON  '  ||  SYSDATE);
  UTL_FILE.NEW_LINE(file);...
  FOR  emp_rec  IN  empc  LOOP
    IF  emp_rec.department  id  <>  olddeptno  THEN
      UTL_FILE.PUT_LINE(file,  'DEPARTMENTL  '  ||  emp_rec.department_id);
      UTL_FILE.NEW_LINE(file);
    END  IF;
    UTL_FILE.PUT_LINE(file,  '  EMPLOYEE:  '  ||  emp_rec.last_name  ||  '  earns:  '  ||  emp_rec.salary);
    olddeptno  :=  emp_rec.department_id;
    UTL_FILE.NEW_LINE(file);
EXCEPTION
  WHEN UTL_FILE.INVALID_FILEHANDLE  THEN
    RAISE  APPLICATION_ERROR(-20001,  'Invalid File.');
  WHEN  UTL_FILE.WRITE_ERROR  THEN
    RAISE_APPLICATION_ERROR(-20002,  'Unable to  write to file');
END  sal_status;
/

HTP

HTP 可以用于生成HTML文档,浏览器就能通过Oracle HTTP Server 和 PL/SQL 网关(mod_plsql)服务访问生成的HTML文档,不及如此,iSQL * Plus 脚本也可以展示HTML文档。


HTP.JPG

使用HTP Package Procedures

生成html标签

htp.bold('Hello');
htp.print('Hi  World');
SET  SERVEROUTPUT  ON
DECLARE
param_val  owa.vc_arr;
BEGIN
  param_val(1)  :=  1;
  owa.init_cgi_env(param_val);
    HTP.HTMLOPEN;  --generates  
    HTP.HEADOPEN;  --generates  
    HTP.TITLE('Hello');  --generates Hello
    HTP.HEADCLOSE;  --generates  
    HTP.BODYOPEN;  --generates  
    HTP.HEADER(1,  'Hello');  --generates  

Hello

HTP.BODYCLOSE; --generates HTP.HTMLCLOSE; --generates htp.showpage(); END; /

UTL_MAIL

UTL_MAIL是一个邮件发送工具,具有cc附件等功能,为用户提供了3个procedure:

  1. SEND:发送无附件邮件
  2. SEND_ATTACH_RAW:带二进制格式附件
  3. SEND_ATTCH_VARCHAR2:带文本格式附件

需要为其配置SMTP_OUT_SERVER参数。

安装和使用UTL_MAIL

ALTER  SYSTEM  SET  SMTP_OUT_SERVER='smtp.server.com'
SCOPE=SPFILE

@?/rdbms/admin/utlmail.sql
@?/rdbms/admin/prvtmail.sql

BEGIN
  UTL_MAIL.SEND('[email protected]',  '[email protected]',  
  message  =>  'For latest  downloads  visit  OTN',   
  subject  =>  'OTN  Newsletter');
END;

发送二进制附件

使用UTL_MAIL.SEND_ATTACH_RAW procedure:

CREATE  OR  REPLACE  PROCEDURE  send_mail_logo  IS
BEGIN
  UTL_MAIL.SEND_ATTACH_RAW(
  sender  =>  '[email protected]',
  recipient  =>  '[email protected]',
  message  =>  
    'See  attachment',
  subject  =>  'Oracle  Logo',
  mime_type  =>  'text/html',
  attachment  =>  get_image('oracle.gif'),
  att_inline  =>  true,
  att_mime_type  =>  'image/gif',
  att_filename  =>  'oralogo.fig');
END;
/

发送文本附件

使用UTL_MAIL.SEND_ATTACH_VARCHAR2 procedure:

CREATE  OR  REPLACE  PROCEDURE  send_mail_file  IS
BEGIN
  UTL_MAIL.SEND_ATTACH_VARCHAR2(
    sender  =>  '[email protected]',
    recipients  =>  '[email protected]',
    message  =>  
      'See  attachment',
      subject  =>  'Oracle  Notes',
      mime_type  =>  'text/html',
      attachment  =>  get_file('notes.txt'),
      att_inline  =>  false;
      att_mime_type  =>  'text/plain',
      att_filename  =>  'notes.txt');
END;
/

DBMS_SCHEDULER

在Oracle中可以创建job,job可以由两个部分构成:

  1. program:What should be executed
  2. schedule:When it should be run


    job.JPG

创建简单的job

BEGIN
  DBMS_SCHEDULER.CREATE_JOB(
    job_name  =>  'JOB_NAME',
    job_type  =>  'PLSQL_BLOCK',
    job_action  =>  'BEGIN insert into  time_test  values(sysdate);
                     commit;
                     END;',
    start_date  =>  SYSTIMESTAMP,
    repeat_interval  =>  'FREQUENCY=HOURLY;INTERVAL=1',
    enabled  =>  TRUE);
END;
/

创建带参数的program

  • 创建一个program
DBMS_SCHEDULER.CREATE_PROGRAM(
  program_name  =>  'PROG_NAME',
  program _type  =>  'STORED_PROCDURE',
  program_action =>  'EMP_REPORT');
  • 定义参数
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(
  program_name  =>  'PROG_NAME',
  argument_name  =>  'DEPT_ID',
  argument_position  =>  1,
  argument_type  =>  'NUMBER',
  default_value  =>  '50');
  • 创建一个job,并指定参数的数量
DBMS_SCHEDULER.CREATE_JOB('JOB_NAME',
  program_name  =>  'PROG_NAME',
  start_date  =>  SYSTIMESTAMP,
  repeat_interval  =>  'FREQ=DAILY',
  number_of_arguments  =>  1,
  enabled  =>  TRUE);

使用Schedule来创建job

BEGIN
  DBMS_SCHEDULER.CREATE_SCHEDULE('SCHED_NAME',
  start_date  =>  SYSTIMESTAMP,
  repeat_interval  =>  'FREQ=DAILY',
  end_date  =>  SYSTIMESTAMP+15);
END;
BEGIN
  DBMS_SCHEDULER.CREATE_JOB('JOB_NAME',
  schedule_name  =>  'SCHED_NAME',
  job_type  =>  'PLSQL_BLOCK',
  job_action  =>  'BEGIN ...; END;',
  enabled  =>  TRUE);
END;

设置Repeat Interval 参数

  • 使用 calendar 表达式
repeat_interval  =>  'FREQ=HOURLY;  INTERVAL=4'
repeat_interval  =>  'FREQ=DAILY'
repeat_interval  =>  'FREQ=MINUTELY;  INTERVAL=15'
repeat_interval  =>  'FREQ=YEARLY;
                      BYMONTH=MAR,  JUN,  SEP,  DEC;
                      BYMONTHDAY=15'
  • 使用PL/SQL 表达式
repeat_interval  =>  'SYSDATE  +  36/24'
repeat_interval  =>  'SYSDATE  +  1'
repeat_interval  =>  'SYSDATE  +  15/(24*60)'

管理Jobs

  • Run a job
DBMS_SCHEDULER.RUN_JOB('SCHEMA.JOB_NAME');
  • Stop a job
DBMS_SCHEDULER.STOP_JOB('SCHEMA.JOB_NAME');
  • 删除一个Job,即使这个Job还在运行中
DBMS_SCHEDULER.DORP_JOB('SCHEMA.JOB_NAME',  TRUE);

相关数据字典

  • [DBA | ALL | USER]_SCHEDULER_JOBS
  • [DBA | ALL | USER]_SCHEDULER_RUNNING_JOBS
  • [DBA | ALL]_SCHEDULER_JOB_CLASSES
  • [DBA | ALL | USER]_SCHEDULER_JOB_LOG
  • [DBA | ALL | USER]_SCHEDULER_JOB_RUN_DETAILS
  • [DBA | ALL | USER]_SCHEDULER_PROGRAMS

你可能感兴趣的:(Oracle SQL 学习笔记24 - Oracle 预定义的package)