Oracle 使用DBMS_SCHEDULER创建定时任务

在Oracle10g里面,已经不赞成使用DBMS_JOB,推荐使用DBMS_SCHEDULER,它的健壮为调度提供更好的规划和结构。下面我只简单写一个例子。
begin
    DBMS_SCHEDULER.CREATE_PROGRAM(
    program_name => 'guozhw',
    program_type => 'STORED_PROCEDURE',
    program_action => 'guozhwTest',
    number_of_arguments => 0,
    enabled => true,
    comments => '定时调度测试'
    );
end;
program_name:program的名字
program_type:program的类型。STORED_PROCEDURE存储过程
program_action:要执行的程序。guozhwTest 存储过程的名字

 

 

举例如下:

BEGIN
      DBMS_SCHEDULER.CREATE_PROGRAM (
         program_name            => 'PRM_CREATEDUNDATA',
         program_action          => 'PKG_SCHEDULER.CREATEDUNDATA',
         program_type            => 'STORED_PROCEDURE',
         enabled                 => FALSE,
     number_of_arguments     => 5,
     comments            => '生成催缴数据'     
     );

  DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(PROGRAM_NAME      => 'PRM_CREATEDUNDATA',
                                         ARGUMENT_POSITION => 1,
                                         ARGUMENT_NAME     => 'I_BILLINGCYCLEID',
                                         ARGUMENT_TYPE     => 'VARCHAR2',
                                         DEFAULT_VALUE     => NULL,
                                         OUT_ARGUMENT      => FALSE);
                                         
  DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(PROGRAM_NAME      => 'PRM_CREATEDUNDATA',
                                         ARGUMENT_POSITION => 2,
                                         ARGUMENT_NAME     => 'I_BUSINESSTYPE',
                                         ARGUMENT_TYPE     => 'VARCHAR2',
                                         DEFAULT_VALUE     => NULL,
                                         OUT_ARGUMENT      => FALSE);

  DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(PROGRAM_NAME      => 'PRM_CREATEDUNDATA',
                                         ARGUMENT_POSITION => 3,
                                         ARGUMENT_NAME     => 'I_STATE',
                                         ARGUMENT_TYPE     => 'VARCHAR2',
                                         DEFAULT_VALUE     => NULL,
                                         OUT_ARGUMENT      => FALSE);
                                         
  DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(PROGRAM_NAME      => 'PRM_CREATEDUNDATA',
                                         ARGUMENT_POSITION => 4,
                                         ARGUMENT_NAME     => 'I_BANKCODE',
                                         ARGUMENT_TYPE     => 'VARCHAR2',
                                         DEFAULT_VALUE     => NULL,
                                         OUT_ARGUMENT      => FALSE);

  DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(PROGRAM_NAME      => 'PRM_CREATEDUNDATA',
                                         ARGUMENT_POSITION => 5,
                                         ARGUMENT_NAME     => 'I_OPERATORCODE',
                                         ARGUMENT_TYPE     => 'VARCHAR2',
                                         DEFAULT_VALUE     => NULL,
                                         OUT_ARGUMENT      => FALSE);

  DBMS_SCHEDULER.ENABLE(NAME => 'PRM_CREATEDUNDATA');
  COMMIT;
END;

 

 

 

之后就可以在select * from sys.USER_SCHEDULER_PROGRAMS t中看到program了

 

 

 

×××××××××××××××××××××××××××××××××××××××××***********************************************************

最近遇到一个CASE,要做定时任务,想来想去,还是先看看Oracle提供了啥..
Oracle10g引入了一种新的作业调度程序:dbms_scheduler,通过如下命令可以查看它包含一些什么功能,
SQL> desc sys.dbms_scheduler;
...
不过,最好还是用PL/SQL dev或者TOAD来展开包头,这样所有功能和注释都一幕了然了。
在Oracle9i,我们都是job来运行定时任务,例如定时备份一些数据,定时清理一下归档。在Oracle10g里面,已经不
赞成试用DBMS_JOB,而是推荐使用DBMS_SCHEDULER,它更加的复杂和健壮,为调度提供更好的规划和结构。
dbms_scheduler把创建一个作业分成了不同的部分:dbms_scheduler,program和job,下面我们依次来创建一个例子。
首先创建一个测试表:
SQL> desc user118800;
Name     Type     Nullable Default Comments
------------- ------------ -------- ------- --------
SN       NUMBER           序列   
AREACODE   VARCHAR2(4)         区号   
DEVICESNUMBER VARCHAR2(12)         电话号码
READ     INTEGER       0   是否读取
BIT     INTEGER           业务位   
DDATE     DATE     Y           
有如下存储过程:
create or replace procedure pro_test is
begin
UPDATE user118800 SET READ=1,ddate=SYSDATE WHERE READ=0 AND ROWNUM <2;
COMMIT;
--sys.dbms_lock.sleep(120);
end pro_test;
这个测试,就是用过程来更新user118800表里面的一行数据,并记录下更新时间,接着我们就创建作业来定时执行。
创建一个scheduler:
/*************************************************************
* Schedule Administration Procedures
*************************************************************
*/
-- Schedule attributes which can be used with set_attribute/get_attribute are :
--
-- repeat_interval   - VARCHAR2
--           an expression using the calendar syntax
-- comments     - VARCHAR2
--           an optional comment.
-- end_date     - TIMESTAMP WITH TIME ZONE
--           cutoff date after which the schedule will not specify
--           any dates
-- start_date   - TIMESTAMP WITH TIME ZONE
--           start or reference date used by the calendar syntax
--
-- Schedules cannot be enabled and disabled.
-- Create a named schedule. This must be a valid schedule.
PROCEDURE create_schedule(
schedule_name     IN VARCHAR2,
start_date       IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
repeat_interval     IN VARCHAR2,
end_date       IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
comments       IN VARCHAR2         DEFAULT NULL);
这是创建scheduler的存储过程,运行如下:
begin
-- Call the procedure
sys.dbms_scheduler.create_schedule(schedule_name => 'your schedule_name',
                start_date => '27-8月 -07 12.00.00.000 上午',
                repeat_interval => 'FREQ=MINUTELY; INTERVAL=1',
                end_date => '28-8月 -07 12.00.00.000 上午',
                comments => 'TEST SCHEDULER');
end;
这里需要注意的是,参数start_date和end_date都是TIMESTAMP 类型,在输入的时候要遵循它们的格式,
往往doc里面的格式都是英文环境下的,这个时候你要通过查询字典nls_database_parameters或者
select to_timestamp(sysdate) from dual; 来获得格式。
repeat_interval是调度运行的时间间隔,本例是每分钟运行一次
repeat_interval => 'FREQ=HOURLY; INTERVAL=1'
每小时运行一次
repeat_interval => 'FREQ=DAILY INTERVAL=1'
每天运行一次
更详细的说明,要查询doc。另外它还有一个过程dbms_scheduler.evaluate_calendar_string是估算下一次运行的时间的。
第二步,创建一个program
/*************************************************************
* Program Administration Procedures
*************************************************************
*/
-- Program attributes which can be used with set_attribute/get_attribute are:
--
-- program_action   - VARCHAR2
--           This is a string specifying the action. In case of:
--           'PLSQL_BLOCK': PLSQL code
--           'STORED_PROCEDURE: name of the database object
--           representing the type (optionally with schema).
--           'EXECUTABLE': Full pathname including the name of the
--           executable, or shell script.
-- program_type   - VARCHAR2
--           type of program. This must be one of the supported
--           program types. Currently these are
--           'PLSQL_BLOCK', 'STORED_PROCEDURE', 'EXECUTABLE'
-- comments       - VARCHAR2
--           an optional comment. This can describe what the
--           program does, or give usage details.
-- number_of_arguments- PLS_INTEGER
--           the number of arguments of the program that can be set
--           by any job using it, these arguments MUST be defined
--           before the program can be enabled
-- enabled       - BOOLEAN
--           whether the program is enabled or not. When the program
--           is enabled, checks are made to ensure that the program
--           is valid.
-- Create a new program. The program name can be optionally qualified with a
-- schema. If enabled is set to TRUE, validity checks will be performed and
-- the program will be created in an enabled state if all are passed.
PROCEDURE create_program(
program_name       IN VARCHAR2,
program_type       IN VARCHAR2,
program_action     IN VARCHAR2,
number_of_arguments   IN PLS_INTEGER DEFAULT 0,
enabled       IN BOOLEAN DEFAULT FALSE,
comments       IN VARCHAR2 DEFAULT NULL);
运行如下:
begin
-- Call the procedure
sys.dbms_scheduler.create_program(program_name => 'your program_name',
                program_type => 'PLSQL_BLOCK',
                program_action => 'BEGIN PRO_TEST; END;',
                number_of_arguments => 0,
                enabled => TRUE,
                comments => 'comments');
end;
这里需要注意的是program_type,如果你要运行PLSQL块,则选择PLSQL_BLOCK,如果是sh脚本,则'EXECUTABLE'。
这里我选择PLSQL块。
第三步创建一个job
-- create a job using a named schedule object and a named program object.
-- If enabled is set TRUE, it will be attempted to enable this job after
-- creating it.
-- Values must be set for each argument of the program that does not have a
-- default_value specified (before enabling the job).
PROCEDURE create_job(
job_name       IN VARCHAR2,
program_name       IN VARCHAR2,
schedule_name     IN VARCHAR2,
job_class       IN VARCHAR2       DEFAULT 'DEFAULT_JOB_CLASS',
enabled       IN BOOLEAN         DEFAULT FALSE,
auto_drop       IN BOOLEAN         DEFAULT TRUE,
comments       IN VARCHAR2       DEFAULT NULL);
实际在10g提供的过程里面,有6中create job的方法,而且也可以单独创建作业,但这里我们选择其中一种。
begin
-- Call the procedure
sys.dbms_scheduler.create_job(job_name => 'my test job',
            program_name => 'your program_name',
            schedule_name => 'your schedule_name',
            job_class => 'DEFAULT_JOB_CLASS',
            enabled => true,
            auto_drop => true,
            comments => 'comments');
end;
这样就完成了一个job的创建,下面就是运行它:
begin
-- Call the procedure
sys.dbms_scheduler.run_job(job_name => 'my test job',
            use_current_session => 'false');
end;
use_current_session 这个参数要定义为false,它才能在后台运行。
创建以后的监控:
查看调度
SELECT * FROM User_Scheduler_Schedules;
查看作业
SELECT * FROM User_Scheduler_Jobs;
查看程序
SELECT * FROM User_Scheduler_Programs;
查看执行中的作业,也就是PRO_TEST在运行阶段的作业。前面的过程中,我定义了一个sys.dbms_lock.sleep(120);
实际就是为了查看这个视图。
SELECT * FROM User_Scheduler_Running_Jobs;
查看job的日志
SELECT * FROM User_Scheduler_Job_Log;
如果日志中有FAILeD的状态,那么就要查看altersid.log了。
好了,一个基本的调度例子就完成了。如果想更详细的了解它,请阅读该包头的注释,和查阅相关DOC
Oracle® Database
PL/SQL Packages and Types Reference
10g Release 2 (10.2)
在9i的时候,job有一个烦人的问题,就是延时,一个job的执行耗时是10分钟,inteval为1天,第一次执行为晚上12点,
在以后的执行过程中,该job为逐渐按10分钟递增时间。10g的Scheduler解决了这个问题,但是我还是发现Scheduler同样无法异步的执行,我的inteval是1分钟,但在程序中如果打开
sleep(120)后,实际inteval就变成了120秒...它还是和job一样,必须等待上一次任务的完成,这样也没有达到我的初衷。
最后,我也应用中是否最终会使用Scheduler,还有待测试。除了Scheduler,在中间层,如EJB和Spring....

 

 

 

 

part 1

1. 创建job

job是什么呢? 简单的说就是计划(schedule)加上任务说明. 另外还有一些必须的参数.

这里提到的"任务"可以是数据库内部的存储过程,匿名的PL/SQL块,也可以是操作系统级别的脚本.

可以有两种方式来定义"计划":
1) 使用DBMS_SCHDULER.CREATE_SCHEDULE 定义一个计划;
2) 调用DBMS_SCHDULER.CREATE_JOBE过程直接指定 (下面会详细说明)

在创建一个计划时,你至少需要指定下面的属性,它们是job运行所必须的:

开始时间 (start_time);

重复频率 (repeat_interval);

结束时间 (end_time)


另外,对于一个job而言,还有很多的附加参数:

job_class
job_priority
auto_drop
restartable
max_runs
max_failures
schedule_limit
logging_level


下面,我以问答的形式来具体解释.


Q1:怎么从数据库中查询job的属性 ?

A1: 有两种方法:

1) 查询(DBA|ALL|USER)_SCHEDULER_JOBS 视图
(提示: 根据用户权限的不同,选择性的查询 DBA|ALL|USER视图)

2) 调用DBMS_SCHEDULER包中的GET_ATTRIBUTE 过程


Q2: 怎么设置这些属性呢?

A2: 也是有两种方法

1) 在创建job时直接指定

2) 调用DBMS_SCHEDULER包中的SET_ATTRIBUTE 过程


Q3: "我需要什么权限才能创建job" ?

A3: 你至少需要create_job这个系统权限。如果用户拥有create any job这个权限,
它可以创建属主为任何用户(SYS用户除外)的job.

缺省情况下,job会被创建在当前的schema下,并且是没有激活的; 如果要使job一创建
就自动激活,需要显式的设置enabled 属性为true, 来看一个例子:

begin
dbms_scheduler.create_job
(
job_name => 'ARC_MOVE',
schedule_name => 'EVERY_60_MINS',
job_type => 'EXECUTABLE',
job_action => '/home/dbtools/move_arcs.sh',
enabled => true,
comments => 'Move Archived Logs to a Different Directory'
);
end;
/


Q4: 能不能详细地讲述一下上面这个过程用到的各个参数?

A4:
job_name: 顾名思义,每个job都必须有一个的名称
schedule_name: 如果定义了计划,在这里指定计划的名称
job_type: 目前支持三种类型:

PL/SQL块: PLSQL_BLOCK,
存储过程: STORED_PROCEDURE
外部程序: EXECUTABLE (外部程序可以是一个shell脚本,也可以是操作系统级别的指令).

job_action: 根据job_type的不同,job_action有不同的含义.
如果job_type指定的是存储过程,就需要指定存储过程的名字;
如果job_type指定的是PL/SQL块,就需要输入完整的PL/SQL代码;
如果job_type指定的外部程序,就需要输入script的名称或者操作系统的指令名

enabled: 上面已经说过了,指定job创建完毕是否自动激活
comments: 对于job的简单说明



2. 指定job的执行频率

如果我们创建了一个job,并且希望它按照我们指定的日期和时间来运行,就需要定义
job的重复频度了. 例如每天运行,每周日的22:00运行, 每周一,三,五运行,每年的
最后一个星期天运行等等.
(说明:10G以前的版本,与操作系统的交互方面,实现的不是很好。例如要实现一个
定期的rman备份任务,就需要结合OS的命令来实现,在UNIX下可以用crontab实现,
在windows下用AT命令来实现)

10G 在这方面有了很大的增强,因为创建job时可以直接指定操作系统的命令或者
脚本,再合理的定义job的执行频率,可以很轻松地完成复杂的调度任务.

10G 支持两种模式的repeat_interval,一种是PL/SQL表达式,这也是dbms_job包
中所使用的,例如SYSDATE+1, SYSDATE + 30/24*60; 另一种就是日历表达式。
例如MON表示星期一,SUN表示星期天,DAY表示每天,WEEK表示每周等等. 下面来
看几个使用日历表达式的例子:

repeat_interval => 'FREQ=HOURLY; INTERVAL=2'
每隔2小时运行一次job

repeat_interval => 'FREQ=DAILY'
每天运行一次job

repeat_interval => 'FREQ=WEEKLY; BYDAY=MON,WED,FRI"
每周的1,3,5运行job

repeat_interval => 'FREQ=YEARLY; BYMONTH=MAR,JUN,SEP,DEC; BYMONTHDAY=30'
每年的3,6,9,12月的30号运行job

用过crontab的人应该都有种似曾相识的感觉吧,呵呵


下面再说说使用日历表达式的规则:

日历表达式基本分为三部分: 第一部分是频率,也就是"FREQ"这个关键字,
它是必须指定的; 第二部分是时间间隔,也就是"INTERVAL"这个关键字,
取值范围是1-999. 它是可选的参数; 最后一部分是附加的参数,可用于
精确地指定日期和时间,它也是可选的参数,例如下面这些值都是合法的:
BYMONTH,BYWEEKNO,BYYEARDAY,BYMONTHDAY,BYDAY
BYHOUR,BYMINUTE,BYSECOND

详细的参数说明请参考 dbms_scheduler的使用说明.

既然说到了repeat_interval,你可能要问:"有没有一种简便的方法来得出,
或者说是评估出job的每次运行时间,以及下一次的运行时间呢?"

dbms_scheduler包提供了一个过程evaluate_calendar_string,可以很
方便地完成这个需求. 来看下面的例子:

SQL> set serveroutput on size 999999

SQL> declare
L_start_date TIMESTAMP;
l_next_date TIMESTAMP;
l_return_date TIMESTAMP;

begin
l_start_date := trunc(SYSTIMESTAMP);
l_return_date := l_start_date;
for ctr in 1..10 loop
dbms_scheduler.evaluate_calendar_string(
'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=7,15',
l_start_date, l_return_date, l_next_date
);

dbms_output.put_line('Next Run on: ' ||
to_char(l_next_date,'mm/dd/yyyy hh24:mi:ss')
);

l_return_date := l_next_date;

end loop;
end;
/


输出结果如下:

Next Run on: 03/22/2004 07:00:00
Next Run on: 03/22/2004 15:00:00
Next Run on: 03/23/2004 07:00:00
Next Run on: 03/23/2004 15:00:00
Next Run on: 03/24/2004 07:00:00
Next Run on: 03/24/2004 15:00:00
Next Run on: 03/25/2004 07:00:00
Next Run on: 03/25/2004 15:00:00
Next Run on: 03/26/2004 07:00:00
Next Run on: 03/26/2004 15:00:00

 

DBMS_SCHEDULER 中度解析: part 2

3. 创建程序 (program)

什么是程序? 我的理解就是准备计划需要的元数据(metadata),它
包括以下部分:

程序名;

程序中用到的参数: 例如程序的类型,以及具体操作的描述

来看一个例子
begin
dbms_scheduler.create_program(
program_name=> 'DAILY_BACKUP_SH',
program_type=> 'EXECUTABLE',
program_action=> '/home/oracle/script/daily_backup.sh');
end;
/

这个例子将会创建一个名为"DAILY_BACKUP_SH"的程序,类型是可执行的shell脚本,脚本的名称是“/home/oracle/script/daily_backup.sh”


Q1: 程序和作业相比,有什么区别呢?

A1: 程序其实是可以与作业分离的,因此不同的用户可以在不同的时间段去重用它.而一个作业是属于特定的用户的;

另外,将程序与作业分离,也就激活了一个新的程序库(Program Library),利用程序库,用户可以很自由地选择特定的程序在特定的时间段运行,以及自由的配置程序执行时的参数.


Q2: 能否解释一下 create_program与create_job的关系?

A2: 首先,你应该知道创建程序并不是一个计划的必须组成部分,一个计划可以没有程序,但是必须有一个已经定义好的作业;
另外,program_action这个参数也是可选的,假如程序的类型是pl/sql 块,你完全可以在创建作业时来指定它.

上面已经提到了,程序和作业可以是分离的,这样一个程序的具体执行(ACTION) 就可以灵活地确定。它既可以只运行一次,也可以在多个不同的作业中来重用这个执行. 这样一来,在修改针对一个作业的计划时就非常灵活,你不需要重新创建pl/sql块.


Q3: 运行 create_program需要什么权限 ?

A3: 要保证create_program能够顺利执行,你同样需要CREATE JOB这个系统权限. 如果一个用户拥有了create any job这个权限,它就可以创建属主为任何用户的程序(SYS用户除外)

与创建作业一样,一个程序建立完毕,缺省的状态也是非激活的,当然你可以在创建程序时,显式的设置enabled参数为true来
激活它.


Q4: 能否介绍一下create_program这个过程的各个参数?
更多的例子?

A4:
program_name: 指定程序的名称;

program_type: 目前只支持下面三种:
STORED_PROCEDURE
PLSQL_BLOCK
EXECUTABLE

program_action: (有长度限制,因为类型是varchar2)

存储过程的名称;
具体的pl/sql代码
操作系统脚本名称


来看一个使用pl/sql块的例子
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(
program_name => 'LEO.UPDATE_STATS',
program_type => 'PLSQL_BLOCK',

program_action => 'DECLARE
sUsername varchar2(30);

cursor cur is select username from dba_users
where username not in ('SYS','SYSTEM','SYSMAN','DBSNMP')
and account_status='OPEN' and substr(username,1,5)<>'MGMT_' ;

BEGIN

OPEN cur;
FETCH cur into sUsername;

WHILE cur%Found
LOOP
DBMS_STATS.GATHER_SCHEMA_STATS (sUsername);

FETCH cur into sUsername;
END LOOP;

close cur;

END;');

END;
/

上面这个例子创建一个名为"UPDATE_STATS"的程序,它的类型是PL/SQL 块,完成更新非系统用户的统计信息的工作。在这个基础上你可以定制一个合理的计划,来定期执行这个程序.



4. 配置程序的参数

先来看一个例子

begin
dbms_scheduler.create_program(
program_name=> 'LEO.UPDATE_STATS_2',
program_action=> 'LEO.UPDATE_SCHEMA_STATUS');
program_type=> 'STORED_PROCEDURE',
number_of_arguments => 1,
enabled => TRUE);

dbms_scheduler.define_program_argument(
program_name=> 'UPDATE_STATS_2',
argument_name => 'SCHEMA_NAME',
argument_position => 1,
argument_type => 'varchar2',
default_value => 'HR');
end;
/

这个例程是不是很像上面的那个例子呢? 对,它们的区别只是
在这个例子中,程序的类型是存储过程,而不是pl/sql块.

解释:
使用define_program_argument这个过程来定义一个程序所需要的参数. 有两点说明一下:

1) 程序如果使用了参数,就必须事先指定,这样才能在程序被job使用时生效;

2) 定义程序的参数不会改变程序的激活属性。也就是说,如果一个程序是没有激活的状态,运行了define_program_argument过程不会自动激活这个程序.


关于权限:
缺省情况下只有program的owner才能修改创建的程序,如果用户被授予了alter 权限 或者 create any job权限,就可以修改属主为另一个用户的程序.



5. 创建计划(Schedule)

其实,如果你已经了解了怎样创建作业和程序,就等于已经掌握怎样创建计划了。你需要做的附加工作只是指定计划的开始时间,结束时间,重复频率等等.

来看一个例子

begin
dbms_scheduler.create_job(
job_name=> 'leo.UPDATE_STATS_JOB',
program_name=> 'leo.UPDATE_STATS_2',
start_date=>'2005-06-20 11:00.00.000000 PM +8:00',
repeat_interval=>'FREQ=MONTHLY;INTERVAL=1',
end_date=>'2006-06-20 11:00.00.000000 PM +8:00',
comments=>'Monthly statistics collection job');
end;
/

start_date和end_date这两个参数需要说明一下: 它们的数据类型
是timestamp,因此需要精确的指定时间和时区. 时间格式继承的是NLS_DATE_FORMAT这个初始化参数的值.

下一部分介绍:
1) 配置作业的参数;
2) 创建/使用/管理作业,程序,计划所需要的系统权限.



一些补充

1.在10G R2 中, 如果用dbms_scheduler创建的job的类型为executable, 需要create external job 权限。

2. 在使用create_job或者create_schedule前,请先检查
NLS_DATE_LANGUAGE, NLS_DATE_FORMAT,
NLS_TIMESTAMP_FORMAT, NLS_TIMESTAMP_TZ_FORMAT
等参数的值, 通过alter session 命令来修改

例如:
SQL> select * from nls_session_parameters;

alter session set NLS_DATE_LANGUAGE='AMERICAN';
alter session set NLS_DATE_FORMAT='dd-mm-yyyy hh24:mi:ss';
alter session set NLS_TIMESTAMP_TZ_FORMAT='dd-mm-yyyy HH:MI:SS.FF AM TZR'

begin
dbms_scheduler.create_job(
job_name=> 'zip_emlog',
job_type=> 'EXECUTABLE',
job_action =>'/home/leo/zip_log.sh',
enabled=>true,
start_date=>'03-07-2005 9:30:00 PM + 8:00',
repeat_interval=>'FREQ=MINUTELY;INTERVAL=30',
end_date=>'31-07-2005 9:30:00 PM + 8:00',
comments=>'Get a latest em log copy and compress it every 30 minutes');
end;

/




----------------------------------------------------------------

dbms_scheduler介绍
10g引入的这个dbms_scheduler包,替代了之前的dbms_job包,该包功能更强大,可以将job需要的各种资源分开再进行 组合。

1.program
1.1 create_program
参数说明:
  program_name——程序名称
  program_type——程序类型(STORED_PROCEDURE,PLSQL_BLOCK,EXECUTABLE)
      STORED_PROCEDURE——ORACLE 中定义好的存储过程
      PLSQL_BLOCK——是一段标准的pl/sql 代码
      EXECUTABLE——指定外部命令的命令行信息(含路径信息)
  program_action——具体对应的执行内容,若为过程则为过程名
  enable——若为true则创建后激活反之不激活
  comments——注释
例子:
BEGIN
   dbms_scheduler.create_program(program_name        => 'myprogram',
                                 program_type        => 'STORED_PROCEDURE',
                                 program_action      => 'p_test1',
                                 number_of_arguments => 1,
                                 enabled             => FALSE,
                                 comments            => '更新gi_pipe表');
   
END;
注:如果创建的程序需要输入参数,则必须定义完参数后在激活,即创建这个program时将enable设为false,否则提示:
    Ora-27456:程序“ ”的参数并未全部定义;然后再对该program定义参数即执行define_program_argument过程(见1.3)。

--查看定义的program
SELECT * FROM user_scheduler_programs;

1.2 drop_program
参数说明:
program_name——要删除的程序名称
force——true或者false。如果为true则不管该program是否被job引用都会删除,FALSE则若被引用无法删除,默认为false。
例子:
BEGIN
   dbms_scheduler.drop_program(program_name => 'myprogram',force => TRUE);
END;

1.3 define_program_argument
参数说明:
program_name——程序名称
argument_position——参数位置(也可以知道参数名称选择argument_name)
argument_type——参数类型
default_value——参数默认值

例子:
BEGIN
   dbms_scheduler.define_program_argument(program_name      => 'myprogram',
                                          argument_position => 1,
                                          argument_name     => 'p_lttid',
                                          argument_type     => 'varchar2',
                                          default_value     => 'daaa');
END;

--查看定义的program参数    
SELECT *FROM User_Scheduler_Program_Args;

1.4 define_anydata_argument(用于定义输入参数为复杂类型需采用sys.AnyData类型来包装的参数)
参数说明:
program_name——程序名称
argument_position——参数位置(也可以知道参数名称选择argument_name)
argument_type——参数类型为sys.AnyData
default_value——参数默认值


1.5 define_metadata_argument
有效的metadata attributes有: 'job_name', 'job_subname', 'job_owner', 'job_start', 'window_start',
                             'window_end', and 'event_message'.
Metadata Attribute              Data Type                              Description
job_name                        VARCHAR2                               当前执行的job名称
job_subname                     VARCHAR2                               当前执行的job子名称
job_owner                       VARCHAR2                               当前执行的job所有者
job_start                   TIMESTAMP WITH TIME ZONE                   job启动的时间
window_start                TIMESTAMP WITH TIME ZONE                   window打开的时间
window_end                  TIMESTAMP WITH TIME ZONE                   window关闭的时间
event_message                                                          事件触发job启动的信息

例子:(以下metadata_attribute设置为job_name,即以job_start这个值作为输入参数)
BEGIN
   dbms_scheduler.define_metadata_argument(program_name       => 'myprogram',
                                           argument_position  => 1,
                                           argument_name      => 'p_lttid',
                                           metadata_attribute => 'job_start');
END;
                                          

1.6 drop_program_argument
例子:
BEGIN
   dbms_scheduler.drop_program_argument(program_name      => 'myprogram',
                                        argument_position => 1);
END;

2.schedule
2.1 create_schedule
参数说明:
repeat_interval——运行频率
end_date和comments默认可以不填
例子:
BEGIN
   dbms_scheduler.create_schedule(schedule_name   => 'myscheduler',
                                  repeat_interval => 'FREQ=MINUTELY;INTERVAL=2');
END;


2.2 create_event_schedule
创建基于事件的调度,用于当一个特殊事件被抛出时启动一个job。
Event类型     描述
job_started   job启动
job_succeeded job启动成功
job_failed    job失败
job_broken    被禁止或状态改为broken
job_completed job执行完成即完成了限制的最大执行次数或者到达执行指定的结束时间
job_stopped   停止job
job_sch_lim_reached 达到了scheduler的限制设置的值
job_disabled    禁止job
job_chain_stalled  A job running a chain was put into the CHAIN_STALLED state. A running chain becomes
                   stalled if there are no steps running or scheduled to run and the chain evaluation_interval is set to NULL.
                   No progress will be made in the chain unless there is manual intervention.
job_all_events Not an event, but a constant that provides an easy way for you to enable all events
job_run_completed job执行或者失败或者成功或者被停止

参数:
event_condition——tab.user_data
queue_spec——必须先创建一个queue,dbms_aqadm.create_queue

--摘至http://www.233.com/oracle/zhonghe/20080807/104612630.html
BEGIN
   dbms_scheduler.create_event_schedule(schedule_name       => 'acc_mgr_change',
                                        start_date        => systimestamp,
                                        event_condition => 'tab.user_data.event_name = ''acc_mgr_change''',
                                        queue_spec      => 'proc_queue');
end;


2.3 drop_schedule
例子:
BEGIN
  DBMS_SCHEDULER.drop_schedule(schedule_name => 'myscheduler');
END;

3.job
3.1 create_job
参数说明:
job_type:类同上述创建program
job_class DEFAULT 'DEFAULT_JOB_CLASS'
enabled   默认FALSE,其创建后要想执行该job必须先执行enable过程
auto_drop 默认TRUE,即当job执行完毕都到期是否直接删除job
comments  默认NULL
job_style 默认REGULAR
credential_name 默认 NULL
destination_name 默认 NULL

--不采用program和scheduler直接创建job
BEGIN
   dbms_scheduler.create_job(job_name        => 'myjob',
                             job_type        => 'STORED_PROCEDURE',
                             job_action      => 'p_test1',
                             start_date      => '',
                             repeat_interval => 'FREQ=DAILY;INTERVAL=2',
                             enabled         => TRUE,
                             comments        => 'My new job');
END;

--根据program和scheduler创建job
BEGIN
   dbms_scheduler.create_job(job_name      => 'myjob',
                             program_name  => 'myprogram',
                             schedule_name => 'myscheduler');
END;

3.2 run_job
BEGIN
   dbms_scheduler.run_job(job_name => 'myjob2');
END;


3.3 stop_job
BEGIN dbms_scheduler.stop_job(job_name => 'myjob');END;

3.4 copy_job
BEGIN dbms_scheduler.copy_job(old_job =>'myjob' ,new_job =>'myjob2' );END;

3.5 drop_job
BEGIN dbms_scheduler.drop_job(job_name => 'myjob');END;

3.6 set_job_argument_value
设置job的输入参数值,设置后会覆盖原先定义该参数设置的默认值
BEGIN
   dbms_scheduler.set_job_argument_value(job_name          => 'myjob2',
                                         argument_position => 1,
                                         argument_value    => 'qwerer');
END;

3.7 set_job_anydata_value
方法类似3.6,只是设置的参数值类似是sys.anydata

3.8 reset_job_argument_value
重置job参数值,将其置为空

4.group(11g才有的)
4.1 create_group
参数:
group_type——组类型,该组的所有成员必须是同一类型,已有的类型有三种:
            DB_DEST:即成员为目标数据库,执行远程数据库的job;
            EXTERNAL_DEST(External destination):Members are external destinations, for running remote external jobs;
            WINDOW:Members are Scheduler windows
创建时可以指定成员也可不指定,添加成员通过add_group_member过程添加。
BEGIN
   dbms_scheduler.create_group(group_name =>,
                               group_type =>,
                               MEMBER     =>,
                               comments   =>);
END;

4.2 drop_group
删除组

4.3 add_group_member
为组添加成员

4.4 remove_group_member
移除组成员

4.5 create_database_destination
创建目标数据库,用于执行远程job
AGENT——The external destination name of the Scheduler agent to connect. Equivalent to an agent name.
       The external destination must already exist. The external destination representing an agent is
       created automatically on a database instance when the agent registers with that instance.
       An agent‘s name is specified in its agent configuration file. If it is not specified, it defaults
       to the first part (before the first period) of the name of the host it resides on.

DBMS_SCHEDULER.CREATE_DATABASE_DESTINATION (
   destination_name        IN VARCHAR2,--目标数据库名称
   agent                   IN VARCHAR2,--代理名称,事先创建好的
   tns_name                IN VARCHAR2,--tns名称
   comments                IN VARCHAR2 DEFAULT NULL);


4.6 drop_database_destination
4.7 drop_agent_destination

5.jobclass
    Job Classes 相当于创建了一个job组,DBA可以将那些具有相同特性的job,放到相同的Job Classes中,
然后通过对Job Class应用ORACLE中的"资源使用计划"特性,就可以对这些job执行过程中所需要的资源分配情况进行
管理。
5.1 create_job_class
参数:
resource_consumer_group——指定该jobclass所使用的资源分配方式。具体创建方法见dbms_resource_manager.create_consumer_group。
                         jobclass与resource_consumer_group为多对1关系;
                         若为该jobclass指定的resource_consumer_group被删除,则使用默认的resource_consumer_group;
                         若没为jobclass指定具体的resource_consumer_group,则使用默认的resource_consumer_group;
                         若为该jobclass指定的resource_consumer_group不存在,则会提示错误;
                         若为该jobclass指定了resource_consumer_group,则service参数必须设置为空(即这两个参数只能设置其中一个)。

service——一般用于rac环境指定jobclass运行于哪个节点。

logging_level——日志记录级别(DBMS_SCHEDULER.LOGGING_OFF,DBMS_SCHEDULER.LOGGING_RUNS,DBMS_SCHEDULER.LOGGING_FULL)
log_history——日志存放时间,默认30
例子:
BEGIN
   dbms_scheduler.create_job_class(job_class_name          =>,
                                   resource_consumer_group =>,
                                   service                 =>,
                                   logging_level           =>,
                                   log_history             =>,
                                   comments                =>);
END;


5.2 drop_job_class
--删除多个job class用逗号隔开
BEGIN
   dbms_scheduler.drop_job_class(job_class_name => '');
END;

6.window
   通常job启动后,用户只能被动地等待其执行,一直到其执行地任务完成(或DBA手动kill对应进程),在此期间,
执行的job将与其它活动的进程共同竞争当前系统中的资源。在9i之前就是这样。在Job Classes中也可以控制job能够
使用的资源,不过单单使用Job Classes并不能灵活的控制job在合适的时间使用适当的资源。进入10g之后,采用
dbms_scheduler的WINDOW可以缓解该问题。WINDOW 可以指定一个时间窗口,在此期间,通过与Job Classes的搭配组合,
能够有效控制job执行时支配(使用)的资源。比如说job通常是在凌晨服务器负载较低时执行,那么就可以通过WINDOW
设置在此期间,允许jobs使用更多的系统资源,而到了工作时间后,如果job仍未执行完成,为其分配另一个有限的
资源,以尽可能降低job执行占用的资源对其它业务的影响。

6.1 create_window
参数:
resource_plan——资源计划,即通过 dbms_resource_manager.create_plan来创建。
schedule_name——调度名称,基于已经创建好的调度创建window。
duration——时间窗口打开后持续的时间,创建时必须设置该值,因为没有默认值,设置范围从1分钟到99天。
window_priority——window优先级,如果同一时间出现多个window时则根据优先级决定执行哪个。
--创建一个基于调度的window
BEGIN
   dbms_scheduler.create_window(window_name     =>,
                                resource_plan   =>,
                                schedule_name   =>,
                                duration        =>,
                                window_priority =>,
                                comments        =>);
END;

--不基于时间调度创建window
DBMS_SCHEDULER.CREATE_WINDOW (
   window_name             IN VARCHAR2,
   resource_plan           IN VARCHAR2,
   start_date              IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
   repeat_interval         IN VARCHAR2,
   end_date                IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
   duration                IN INTERVAL DAY TO SECOND,
   window_priority         IN VARCHAR2                 DEFAULT 'LOW',
   comments                IN VARCHAR2                 DEFAULT NULL);

6.2 drop_window
删除一个window。

6.3 open_window
打开一个window。

6.4 close_window
关闭一个window。


7.windowgroup
    一个WINDOW GROUP可能包含多个WINDOW。使用WINDOW GROUP的本意是这样的,假如说某个job执行的时间比较长,
甚至全天24小时都在执行,对于这类job,单个WINDOW很难有效调整其资源占用,因此就可以通过设置一个
WINDOW GROUP,该WINDOW GROUP中包含了多个WINDOW,每个WINDOW分别负责不同时间点时的资源使用计划。然后在
创建JOB时,指定schedule_name参数为WINDOW GROUP的名称,当然也可以直接指定window名称
(window已经包含了调度信息了)。

7.1 create_window_group
BEGIN
   dbms_scheduler.create_window_group(group_name  =>,
                                      window_list =>,
                                      comments    =>);
END;

7.2 add_window_group_member
增加一个window
BEGIN
   dbms_scheduler.add_window_group_member(group_name => ,window_list => );
END;

7.3 remove_window_group_member
移除一个window

7.4 drop_window_group
删除一个window


8.chain 参考http://hi.baidu.com/sqlnever/item/be05b1abba1611fc15329b86
    CHAIN可以被视做多个program放到同一个链中,这样的话就可以指定这些program执行的先后顺序。
8.1 create_chain
DBMS_SCHEDULER.CREATE_CHAIN (
   chain_name              IN VARCHAR2,
   rule_set_name           IN VARCHAR2 DEFAULT NULL,
   evaluation_interval     IN INTERVAL DAY TO SECOND DEFAULT NULL,
   comments                IN VARCHAR2 DEFAULT NULL);


8.2 define_chain_rule
定义规则
举例,如my_step1执行完则执行my_step2,若my_step2执行完则结束
BEGIN
   dbms_scheduler.define_chain_rule(chain_name => 'my_chain1',
                                    condition  => 'TRUE',
                                    action     => 'start my_step1',
                                    rule_name  => 'my_rule1');
   dbms_scheduler.define_chain_rule(chain_name => 'my_chain1',
                                    condition  => 'my_step1 completed',
                                    action     => 'start my_step2',
                                    rule_name  => 'my_rule2');
   dbms_scheduler.define_chain_rule(chain_name => 'my_chain1',
                                    condition  => 'my_step2 completed',
                                    action     => 'end 0',
                                    rule_name  => 'my_rule3');
END;

8.3 define_chain_step
 BEGIN
    dbms_scheduler.define_chain_step(chain_name   => 'my_chain1',
                                     step_name    => 'my_step1',
                                     program_name => 'p_p2');
    dbms_scheduler.define_chain_step(chain_name   => 'my_chain1',
                                     step_name    => 'my_step2',
                                     program_name => 'p_p3');
 END;

8.4 define_chain_event_step
BEGIN
   dbms_scheduler.define_chain_event_step(chain_name          =>,
                                          step_name           =>,
                                          event_schedule_name =>,
                                          timeout             =>);
END;

8.5 drop_chain_rule
dbms_scheduler.drop_chain_rule(chain_name => ,rule_name => );

8.6 drop_chain_step
dbms_scheduler.drop_chain_step(chain_name => ,step_name => );

8.7 alter_chain
dbms_scheduler.alter_chain(chain_name => ,step_name => ,attribute => ,value => );

8.8 drop_chain

8.9 analyze_chain
dbms_scheduler.analyze_chain(chain_name => ,rules => ,steps => ,step_pairs => );

8.10 alter_running_chain
dbms_scheduler.alter_running_chain(job_name => ,step_name => ,attribute => ,value => );

8.11 evaluate_running_chain
dbms_scheduler.evaluate_running_chain(job_name => );

8.12 run_chain
dbms_scheduler.run_chain(chain_name => ,start_steps => ,job_name => );


9.credential
创建用户名密码,用于认证job执行
9.1 create_credential
BEGIN
   dbms_scheduler.create_credential(credential_name =>,
                                    username        =>,
                                    password        =>,
                                    database_role   =>,
                                    windows_domain  =>,
                                    comments        =>);
END;

9.2 drop_credential
9.3 put_file
BEGIN
   dbms_scheduler.put_file(destination_file        =>,
                           destination_host        =>,
                           credential_name         =>,
                           file_contents           =>,
                           destination_permissions =>);
END;

9.4 get_file
9.5 create_file_watcher
BEGIN
   dbms_scheduler.create_file_watcher(file_watcher_name     =>,
                                      directory_path        =>,
                                      file_name             =>,
                                      credential_name       =>,
                                      destination           =>,
                                      min_file_size         =>,
                                      steady_state_duration =>,
                                      comments              =>,
                                      enabled               =>);
END;

9.6 drop_file_watcher
9.7 add_job_email_notification
BEGIN
   dbms_scheduler.add_job_email_notification(job_name         =>,
                                             recipients       =>,
                                             sender           =>,
                                             subject          =>,
                                             BODY             =>,
                                             events           =>,
                                             filter_condition =>);
END;

9.8 remove_job_email_notification

10.通用的
10.1 DISABLE
BEGIN
   dbms_scheduler.disable(NAME => 'myjob2');
END;

10.2 enable
BEGIN
   dbms_scheduler.enable(NAME => 'myprogram');
END;

BEGIN
   dbms_scheduler.enable(NAME => 'myjob2');
END;

10.3 set_attribute
attribute:是指设置job的属性,属性有:
logging_level——记录的日志信息,有三个值(DBMS_SCHEDULER.LOGGING_OFF,DBMS_SCHEDULER.LOGGING_RUNS,
                                         DBMS_SCHEDULER.LOGGING_FULL)
restartable——设置job失败是否要重启
max_failures——允许job失败的次数,范围1到1000000,默认为空。
max_runs——job执行的最大次数,范围1到1000000,默认为空(即意味着job会重复执行,或者到达job执行的end_date,或者达到指定失败的次数)。
          一旦达到设置的最大值,job将会disable并且状态变更为COMPLETED
max_run_duration——设置job运行的有效时间,如果设置了某个值,则在到达该值时调度会报JOB_OVER_MAX_DUR事件,
                  然后由事件处理器决定是否要继续
instance_stickiness——只用于rac数据库。默认为true,设置为true,则job会运行在负载最轻的节点上;如果某节点
                     关闭或负载太重,则不会启动新job,而是有另一个节点来执行该job。
stop_on_window_close——window关闭的时候停止job,默认为false。因此默认情况下关闭了window,job还是会继续执行,
                      但是要注意,window关闭则意味着资源使用计划就会变化。
job_priority——在同一个class,job执行的优先级,默认为3.
schedule_limit——允许启动job延迟的时间,设置值从1分钟到99天。超过了延迟的时间则不再启动job。如果不设置
                该值,则只要得到允许所需的资源就会启动。另外,在延迟的这段时间里,job的执行次数或失败次数
                会跳过,不计算这段时间的。
program_name——job执行的对象。如果设置了该属性,则job_action, job_type,number_of_arguments要设置为空。
job_action——job执行对象内容
job_type——job执行对象类型('PLSQL_BLOCK', 'STORED_PROCEDURE', 'EXECUTABLE', and 'CHAIN')。如果设置了该值,
          那么program_name参数必须设置为空 。
number_of_arguments——参数个数。如果设置了该值,那么program_name参数必须设置为空。
schedule_name——调度名,如果设置了该值,则end_date, start_date and repeat_interval需设置为空。
repeat_interval——执行间隔,设置了该值,则schedule_name需为空。
start_date——执行开始时间,设置了该值,则schedule_name需为空。
end_date——不再执行job的时间,设置了该值,则schedule_name需为空。
job_class——jobclass
comments——备注
auto_drop——当job状态为completed则自动删除该job
event_spec——需含两个值(event condition和queue specification)
raise_events——设置当job为什么状态时抛出,具体的时间类型见event类型。
 
--设置log_history为90天,默认30天
BEGIN
   dbms_scheduler.set_scheduler_attribute('log_history', '90');
END;

10.4 set_attribute_null
10.5 get_attribute


11.schedulerattribute
设置调度属性的值
11.1 set_scheduler_attribute
attribute类型有:default_timezone,email_server,email_sender,email_server_credential,email_server_encryption,
                event_expiry_time ,log_history,max_job_slave_processes(没使用)

BEGIN
   dbms_scheduler.set_scheduler_attribute(attribute => ,value => );
END;


11.2 get_scheduler_attribute
BEGIN
   dbms_scheduler.get_scheduler_attribute(attribute => ,value => );
END;

11.3 add_event_queue_subscriber
BEGIN
   dbms_scheduler.add_event_queue_subscriber(subscriber_name => );
END;

11.4 remove_event_queue_subscriber
BEGIN
   dbms_scheduler.remove_event_queue_subscriber(subscriber_name => );
END;
11.5 purge_log
BEGIN
   dbms_scheduler.purge_log(log_history => ,which_log => ,job_name => );
END;


dbms_scheduler包一些视图
--*代表all或dba或user
--1.查看job的视图
*_scheduler_jobs --查看job
*_scheduler_job_args  --查看job的所有输入参数
*_scheduler_job_classes --查看job的类信息
*_scheduler_job_dests --查看job状态
*_scheduler_job_log --查看job日志
*_scheduler_job_run_details --查看job执行的详细信息
all_scheduler_running_jobs

--2.查看chain的一些视图
*_scheduler_chains
*_scheduler_chain_rules
*_scheduler_chain_steps
*_scheduler_running_chains --查看正在执行的chains

--3.查看program的视图
*_scheduler_programs --查看程序
*_scheduler_program_args --查看程序参数

--4.查看调度组信息
*_scheduler_groups
*_scheduler_group_members

--5.查看window的视图(这类视图只有dba和all开头的)
*_scheduler_windows --查看window
*_scheduler_window_details --查看window详细信息
*_scheduler_window_groups --查看window组
*_scheduler_window_log --查看window日志
*_scheduler_wingroup_members ----查看window成员

--6.查看scheduler视图
*_scheduler_schedules --查看调度
*_scheduler_global_attribute --显示所有的调度属性
*_scheduler_credentials
*_scheduler_db_dests
*_scheduler_dests
*_scheduler_external_dests
*_scheduler_file_watchers
*_scheduler_notifications
*_scheduler_remote_databases
*_scheduler_remote_jobstate


你可能感兴趣的:(Oracle)