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 读写流程
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 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:
- SEND:发送无附件邮件
- SEND_ATTACH_RAW:带二进制格式附件
- 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可以由两个部分构成:
- program:What should be executed
-
schedule:When it should be run
创建简单的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