美文网首页程序园
Oracle SQL 学习笔记24 - Oracle 预定义的p

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

作者: 赵阳_c149 | 来源:发表于2020-02-10 13:59 被阅读0次

    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  <B>World</B>');
    
    SET  SERVEROUTPUT  ON
    DECLARE
    param_val  owa.vc_arr;
    BEGIN
      param_val(1)  :=  1;
      owa.init_cgi_env(param_val);
        HTP.HTMLOPEN;  --generates  <HTML>
        HTP.HEADOPEN;  --generates  <HEAD>
        HTP.TITLE('Hello');  --generates <Title>Hello</Title>
        HTP.HEADCLOSE;  --generates  </HEAD>
        HTP.BODYOPEN;  --generates  <BODY>
        HTP.HEADER(1,  'Hello');  --generates  <H1>Hello</H1>
        HTP.BODYCLOSE;  --generates  </BODY>
        HTP.HTMLCLOSE;  --generates  </HTML>
      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('otn@oracle.com',  'user@oracle.com',  
      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  =>  'me@oracle.com',
      recipient  =>  'you@somewhere.net',
      message  =>  
        '<HTML><BODY>See  attachment</BODY></HTML>',
      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  =>  'me@oracle.com',
        recipients  =>  'you@somewhere.net',
        message  =>  
          '<HTML><BODY>See  attachment</BODY></HTML>',
          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 预定义的p

        本文链接:https://www.haomeiwen.com/subject/ubjnxhtx.html