﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-david database lab-文章分类-ORACLE</title><link>http://www.blogjava.net/javaex/category/31623.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 15 Nov 2010 17:55:52 GMT</lastBuildDate><pubDate>Mon, 15 Nov 2010 17:55:52 GMT</pubDate><ttl>60</ttl><item><title>Oracle 10g Scheduler 特性 转自 http://blog.csdn.net/tianlesoftware/archive/2009/10/22/4715218.aspx</title><link>http://www.blogjava.net/javaex/articles/303645.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303645.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303645.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303645.html</trackback:ping><description><![CDATA[<p>Oracle 10g Scheduler 特性 <br />
在10g 环境中，ORACLE 建议使用Scheduler 替换普通的job，来管理任务的执行。其实，将Scheduler 描述成管理job 的工具已经太过片面了，10G版本中新增的Scheduler 绝不仅仅是创建任务这么简单.</p>
<p><br />
一． 使用Jobs</p>
<p>所谓JOBS，其实就是Scheduler 管理的一个(或多个)任务的执行调度。</p>
<p><br />
1.1 创建Jobs</p>
<p>通过DBMS_SCHEDULER 包来创建Jobs，是使用其CREATE_JOB 过程。在创建Job 时，用户可以指定要执行的任务，调度信息(啥时候执行，执行周期，终止日期等)以及其它一些任务相关的属性。CREATE_JOB 过程调用还是比较简单的，例如：</p>
<p>create table TEST (id number);</p>
<p><br />
CREATE OR REPLACE PROCEDURE IT</p>
<p>AS</p>
<p>BEGIN</p>
<p>insert into TEST VALUES(1);</p>
<p>END;</p>
<p><br />
SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.CREATE_JOB (</p>
<p>job_name =&gt; 'JobTest',</p>
<p>job_type =&gt; 'STORED_PROCEDURE',</p>
<p>job_action =&gt; 'SYSTEM.IT',</p>
<p>start_date =&gt; sysdate,</p>
<p>repeat_interval =&gt; 'FREQ=MINUTELY;INTERVAL=10');</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL 过程已成功完成。</p>
<p><br />
事实上，有权限的话，用户也可以创建其它SCHEMA 下的JOB，只需要在指定JOB_NAME 时，按照schema.job_name 的格式即可。注意哟，这种情况下创建的JOB，其CREATED 与OWNER 有可能并不相同的哟。</p>
<p>当使用CREATE_JOB 过程创建JOB 时，可指定的参数值很多，只不过多数情况下用户仅指定部分参数即可满足需求。</p>
<p><br />
其中，上例中指定的参数，分别代表的含义如下：</p>
<p>JOB_NAME：指定任务的名称，必选值，注意要确保指定的名称唯一。</p>
<p>JOB_TYPE：任务执行的操作类型，必选值，有下列几个可选值：</p>
<p>&nbsp;&nbsp; PLSQL_BLOCK：表示任务执行的是一个PL/SQL 匿名块。</p>
<p>&nbsp;&nbsp; STORED_PROCEDURE：表示任务执行的是ORACLE 过程(含PL/SQL PROCEDURE 和JAVA</p>
<p>PROCEDURE)，本例中正是指定这一参数值。</p>
<p>&nbsp;&nbsp; EXECUTABLE：表示任务执行的是一个外部程序，比如说操作系统命令。</p>
<p>&nbsp;&nbsp; CHAIN：表示任务执行的是一个CHAIN。</p>
<p>JOB_ACTION：任务执行的操作，必选值，应与JOB_TYPE 类型中指定的参数相匹配。</p>
<p>比如说对于PL/SQL 匿名块，此处就可以放置PL/SQL 块的具体代表，类似DECLARE .. BEGIN ..END这类；如果是ORACLE 过程，那么此处应该指定具体的过程名，注意由于任务执行，即使过程中有OUT之类参数，实际执行时也不会有输出的。</p>
<p>START_DATE：指定任务初次执行的时间，本参数可为空，当为空时，表示任务立刻执行，效果等同于指定该参数值为SYSDATE。</p>
<p>REPEAT_INTERVAL：指定任务执行的频率，比如多长时间会被触发再次执行。本参数也可以为空，如果为空的话，就表示当前设定的任务只执行一次。REPEAT_INTERVAL 参数需要好好说说，因为这一参数与标准JOB 中的INTERVAL 参数有很大区别，相比之下，REPEAT_INTERVAL 参数的语法结构要复杂的多。其中最重要的是FREQ 和INTERVAL 两个关键字。</p>
<p>&nbsp;&nbsp; FREQ 关键字用来指定间隔的时间周期，可选参数有：YEARLY, MONTHLY, WEEKLY, DAILY,HOURLY, MINUTELY, and SECONDLY，分别表示年、月、周、日、时、分、秒等单位。</p>
<p>&nbsp;&nbsp; INTERVAL 关键字用来指定间隔的频繁，可指定的值的范围从1-99。</p>
<p>例如：REPEAT_INTERVAL=&gt;'FREQ=DAILY;INTERVAL=1';表示每天执行一次，如果将INTERVAL 改为7 就表示每7 天执行一次，效果等同于FREQ=WEEKLY;INTERVAL=1。</p>
<p>一般来说，使用DBMS_SCHEDULER.CREATE_JOB 创建一个JOB，至少需要指定上述参数中的前3 项。除此之外，还可以在CREATE_JOB 时，指定下列参数：</p>
<p>&nbsp;&nbsp; NUMBER_OF_ARGUMENTS：指定该JOB 执行时需要附带的参数的数量，默认值为0，注意当JOB_TYPE 列值为PLSQL_BLOCK 或CHAIN 时，本参数必须设置为0，因为上述两种情况下不支持附带参数。</p>
<p>&nbsp;&nbsp; END_DATE：指定任务的过期时间，默认值为NULL。任务过期后，任务的STATE 将自动被修改为COMPLETED，ENABLED 被置为FALSE。如果该参数设置为空的话，表示该任务永不过期，将一直按照</p>
<p>REPEAT_INTERVAL 参数设置的周期重复执行，直到达到设置的MAX_RUNS 或MAX_FAILURES 值。</p>
<p>&nbsp;&nbsp; JOB_CLASS：指定任务关联的CLASS，默认值为DEFAULT_JOB_CLASS。</p>
<p>&nbsp;&nbsp; ENABLED：指定任务是否启用，默认值为FALSE。FALSE 状态表示该任务并不会被执行，除非被用户手动调用，或者用户将该任务的状态修改为TRUE。</p>
<p>&nbsp;&nbsp; AUTO_DROP：当该标志被置为TRUE 时，ORACLE 会在满足条件时自动删除创建的任务</p>
<p>&nbsp;&nbsp; 任务已过期；</p>
<p>&nbsp;&nbsp; 任务最大运行次数已达MAX_RUNS 的设置值；</p>
<p>&nbsp;&nbsp; 任务未指定REPEAT_INTERVAL 参数，仅运行一次；</p>
<p>该参数的默认值即为TRUE。用户在执行CREATE_JOB 过程时可以手动将该标志指定为FALSE，当参数值设置为FALSE 时，即使满足上述提到的条件任务也不会被自动删除，这种情况下，唯一能够导致任务被删除的情况，就是用户主动调用DROP_JOB 过程。</p>
<p>&nbsp;&nbsp; COMMENTS：设置任务的注释信息，默认值为NULL。</p>
<p><br />
上面的例子创建了一个新的JOB，不过这个JOB 与普通JOB 不同哟，此时查询USER_JOBS 视图是查不到刚刚创建的JOB 的信息，因为这个JOB 是SCHEDULER 管理的JOB。要查询SCHEDULER 管理的JOS，应该通过USER_SCHEDULER_JOBS(当然ALL_SCHEDULER_JOBS 和DBA_SCHEDULER_JOBS 也可以)， 例如：</p>
<p><br />
SQL&gt; select job_name,job_type,job_action,to_char(start_date,'yyyy-mm-dd</p>
<p>hh24:mi:ss') TM,repeat_interval,enabled,state from user_scheduler_jobs;</p>
<p>JOB_NAME&nbsp;&nbsp; JOB_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JOB_ACTION TM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REPEAT_INTERVAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENABL STATE</p>
<p>---------- ---------------- ---------- ---------- ------------------------- ------ ------</p>
<p>JOBTEST&nbsp;&nbsp;&nbsp; STORED_PROCEDURE SYSTEM.IT&nbsp; 2009-09-25 FREQ=MINUTELY;INTERVAL=10&nbsp; FALSE DISABLED</p>
<p><br />
不过，细心的盆友可能会发现，JOB 虽然成功创建了，但却并未执行.原因ENABLED 参数当不显式指定时，该参数的默认值为false，JOB自然不会运行了。</p>
<p><br />
1.2 管理Jobs</p>
<p>1.2.1 启用Jobs</p>
<p>前面创建JOB 时，由于未显式的指定ENABLED 参数，因此即使指定了START_DATE，不过默认情况下JOB</p>
<p>不会自动执行。对于这种情况，DBMS_SCHEDULER 包中提供了一个过程ENABLE，可以用来修改JOB 的启</p>
<p>用状态，调用方式非常简单，例如：</p>
<p>SQL&gt; exec dbms_scheduler.enable('JOBTEST');</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
1.2.2 禁用Jobs</p>
<p>DBMS_SCHEDULER.ENABLE 仅用来将JOB(其实不仅仅对JOB 有效，对于CHAIN、PROGRAM 等也有效)的启用状态置为TRUE。如果想将其启用状态置为FALSE？简单，还有一个与该功能对应的过程：</p>
<p>DBMS_SCHEDULER.DISABLE，例如：</p>
<p>JSSWEB&gt; exec dbms_scheduler.disable('JOBTEST');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>这两个过程仅用来重置对象的状态，因此均可以无限次执行，即使执行时对象已经被置为要指定的状态。</p>
<p><br />
1.2.3 修改Jobs</p>
<p>由于JOB 的属性众多，难免时不时的可能会遇到需要修改的情况，比如说前面创建JOB 时不小心，指定要</p>
<p>执行的过程名输入错误(完全有可能，CREATE_JOB 在创建时不会自动检查指定的过程是否有效，从这方面考虑，</p>
<p>SCHEDULER 不如普通JOB 严谨哪)，这种情况下就必然涉及到对JOB 的修改(或者说重定义)，没问题，</p>
<p>DBMS_SCHEDULER 包中专门提供了一个过程SET_ATTRIBUTE，可以用来修改任务的属性值。</p>
<p>例如，修改刚刚创建的JOB：INSERT_TEST_TBL 执行的过程，执行语句如下：</p>
<p>JSSWEB&gt; exec dbms_scheduler.set_attribute('JobTest','JOB_ACTION','SYSTEM.IT');</p>
<p>PL/SQL procedure successfully completed</p>
<p>当然啦，我们这里执行的这条语句，执行跟没执行没有区别，此处仅做示例，大家表深究。</p>
<p><br />
SET_ATTRIBUTE 过程虽然仅有三个参数，不过能够修改的属性值可是不少，以下列举几个较常用到的：</p>
<p>&nbsp;&nbsp; LOGGING_LEVEL：指定对jobs 执行情况记录的日志信息级别。</p>
<p>SCHEDULER 管理的JOB 对任务的执行情况专门进行了记录，同时用户还可以选择日志中记录信息的级别，有下列三种选择：</p>
<p>&nbsp;&nbsp; DBMS_SCHEDULER.LOGGING_OFF：关闭日志记录功能；</p>
<p>&nbsp;&nbsp; DBMS_SCHEDULER.LOGGING_RUNS：对任务的运行信息进行记录；</p>
<p>&nbsp;&nbsp; DBMS_SCHEDULER.LOGGING_FULL：记录任务所有相关信息，不仅有任务的运行情况，甚至连任务的创建、修改等也均将记入日志。</p>
<p>提示： 查看SCHEDULER 管理的JOB ， 可以通过USER_SCHEDULER_JOB_LOG 和USER_SCHEDULER_JOB_RUN_DETAILS 两个视图中查询</p>
<p>&nbsp;&nbsp; RESTARTABLE：指定jobs 运行出错后，是否能够适时重启创建任务时如未明确指定，本参数默认情况下设置为FALSE，如果设置为TRUE，就表示当任务运行时出错，下次运行时间点到达时仍会启动，并且如果运行仍然出错，会继续重新运行，不过如果连接出错达到6 次，该job 就会停止。</p>
<p>&nbsp;&nbsp; MAX_FAILURES：指定jobs 最大连续出错次数该参数值可指定的范围从1-1000000，默认情况下该参数设置为NULL，表示无限制。达到指定出错次数后，该job 会被自动disable。</p>
<p>&nbsp;&nbsp; MAX_RUNS：指定jobs 最大运行次数</p>
<p>该参数值可指定的范围从1-1000000，默认情况下该参数设置为NULL，表示无限制(只是运行次数无限制，实际job 会否继续运行，仍受制于end_date 以及max_failures 等参数的设置)。达到指定运行次数后，该job 也将被自动disable，并且状态会被置为COMPLETED。</p>
<p>&nbsp;&nbsp; JOB_TYPE：指定job 执行的任务的类型</p>
<p>有四个可选值：'PLSQL_BLOCK', 'STORED_PROCEDURE', 'EXECUTABLE', and 'CHAIN'。</p>
<p>&nbsp;&nbsp; JOB_ACTION：指定job 执行的任务.这一参数所指定的值依赖于JOB_TYPE 参数中的值， 比如说JOB_TYPE 设置为</p>
<p>'STORED_PROCEDURE'，那么本参数值中指定的一定是ORACLE 中的过程名。</p>
<p>&nbsp;&nbsp; START_DATE：指定job 初次启动的时间</p>
<p>&nbsp;&nbsp; END_DATE：指定job 停止运行的时间</p>
<p>本参数又与AUTO_DROP 相关联，如果AUTO_DROP 设置为TRUE 的话，那么一旦job 到达停止运行的时间，该job 就会被自动删除，否则的话job 任何存在，不过状态被修改为COMPLETED。</p>
<p>除此之外， 其它还包括MAX_RUN_DURATION ， JOB_WEIGHT ， INSTANCE_STICKINESS ，STOP_ON_WINDOW_CLOSE ， JOB_PRIORITY ， SCHEDULE_LIMIT ， PROGRAM_NAME ，NUMBER_OF_ARGUMENTS ， SCHEDULE_NAME ， REPEAT_INTERVAL ， JOB_CLASS ， COMMENTS ，AUTO_DROP，EVENT_SPEC，RAISE_EVENTS 等等，这些参数所代表的意义此处不一一详述，感兴趣的朋友</p>
<p><br />
仅从这些可设置属性就可以看出，Scheduler 管理的job 确实非常灵活，上述提到了这些参数，均可以使用</p>
<p>DBMS_SCHEDULER.SET_ATTRIBUTE 过程进行设置。</p>
<p><br />
另外需要注意一点，除了用户手动创建的jobs 之外，数据库在运行过程中也有可能自动创建jobs。对于这</p>
<p>类jobs 除非必要，否则不建议进行修改。至于如何区分jobs 是用户创建，还是数据库自动创建，可以通过</p>
<p>*_SCHEDULER_JOBS 视图的SYSTEM 列来确定，如果该列显示为TRUE，则表示由系统创建</p>
<p><br />
1.2.4 执行Jobs</p>
<p>虽然说jobs 大多都应该是自动执行，不过经过前面的示例，大家想必也认识到了，并不是说创建了jobs 它</p>
<p>就会自动执行，是否能够真正自动执行并不是由你的主观意愿就能直接决定，而是由jobs 自身的多个相关属性</p>
<p>决定。</p>
<p>关于jobs 自动执行的话题相信看完前面的内容后，应该都知道如何设置，下面主要演示，如何手动调用jobs</p>
<p>并执行，这其中，当然少不了DBMS_SCHEDULER 包。例如，手动执行前面刚刚创建的job:JOBTEST：</p>
<p>JSSWEB&gt; exec dbms_scheduler.run_job('JOBTEST');</p>
<p>PL/SQL procedure successfully completed</p>
<p>Jobs 每执行一次，无论成功或失败，均会在*_SCHEDULER_JOB_LOG 中生成一条对应的记录(前提是LOGGING_LEVEL 属性值未设置为DBMS_SCHEDULER.LOGGING_OFF) ， 同时， 用户也可以通过*_SCHEDULER_JOB_RUN_DETAILS 视图查询job 执行的详细信息。</p>
<p><br />
1.2.5 停止Jobs</p>
<p>停止job 可以使用DMBS_SCHEDULER.STOP_JOB 过程，例如：</p>
<p>JSSWEB&gt; exec dbms_scheduler.stop_job('JOBTEST');</p>
<p>PL/SQL procedure successfully completed</p>
<p><br />
注意，STOP_JOB 过程不仅仅是更新job 的状态，而是停止当前正在执行的任务，如果你处理的任务当前未在运行的话，那么执行STOP_JOB 过程，会触发ORA-27366 错误。</p>
<p>停止Jobs 也会触发一条任务的日志信息，对于执行停止操作的job，其*_SCHEDULER_JOB_LOG 视图的OPERATION 会记录为'STOPPED'，ADDITIONAL_INFO 列中记录的信息类似'REASON="Stop job called by user:username"'。</p>
<p><br />
1.2.6 删除Jobs</p>
<p>删除创建的job 就比较简单了，直接执行DBMS_SCHEDULER.DROP_JOB 过程即可，例如：</p>
<p>JSSWEB&gt; exec dbms_scheduler.drop_job('JOBTEST');</p>
<p>PL/SQL procedure successfully completed</p>
<p>删除jobs 并不是修改该job 中某个字段的标记值，而是直接删除其在数据字典中的字义，因此被删除的job</p>
<p>如果未来发现仍然需要，只能重建，而无法通过其它方式快速恢复。不过，删除jobs 的操作，并不会级联删除</p>
<p>这些job 曾经执行过的日志信息。</p>
<p><br />
二、使用Programs</p>
<p>进入10g 版本之后，可以在ORACLE 中执行操作系统命令，或是ORACLE 数据库外的应用，因为有了DBMS_SCHEDULER，因为有了PROGRAM。</p>
<p><br />
2.1 创建Programs</p>
<p>Scheduler 中的Program 对象并不是常规意义上的"程序"或"应用"，而就是一个"对象"，由DBA 定义的，具</p>
<p>有执行某项功能的特殊对象。Program 中实际执行的操作可以分为下列三种类型：</p>
<p>&nbsp;&nbsp; PL/SQL BLOCK：标准的pl/sql 代码块；</p>
<p>&nbsp;&nbsp; STORED PROCEDURE：编译好的PL/SQL 存储过程，或者Java 存储过程，以及外部的子程序；</p>
<p>&nbsp;&nbsp; EXECUTEABLE：ORACLE 数据库之外的应用，比如操作系统命令等等。</p>
<p>创建Programs 使用DBMS_SCHEDULER.CREATE_PROGRAM 过程，该过程支持的参数如下：</p>
<p>SQL&gt; desc dbms_scheduler.create_program;</p>
<p>Parameter Type Mode Default</p>
<p>------------------- -------------- ---- --------</p>
<p>PROGRAM_NAME VARCHAR2 IN</p>
<p>PROGRAM_TYPE VARCHAR2 IN</p>
<p>PROGRAM_ACTION VARCHAR2 IN</p>
<p>NUMBER_OF_ARGUMENTS BINARY_INTEGER IN Y</p>
<p>ENABLED BOOLEAN IN Y</p>
<p>COMMENTS VARCHAR2 IN Y</p>
<p>如上所示，前三项为必选参数，各参数实际代表的意义如下：</p>
<p>&nbsp;&nbsp; PROGRAM_NAME：指定一个program 名称；</p>
<p>&nbsp;&nbsp; PROGRAM_TYPE：Program 的类型，如前文中所述，Program 支持三种类型；</p>
<p>&nbsp;&nbsp; PROGRAM_ACTION：实际执行的操作，应与前面PROGRAM_TYPE 参数关联使用。比如说前面指定</p>
<p>了PROGRAM_TYPE 为"PLSQL_BLOCK"，那么此处要执行的action 就应当是一段标准的pl/sql 代码。如果前</p>
<p>面指定PROGRAM_TYPE 为"STORED_PROCEDURE"，那么此处要执行的action 就应当是ORACLE 中定义好</p>
<p>的存储过程(含Java 存储过程)，如果前面指定PROGRAM_TYPE 为"EXECUTABLE"，那么此处就应该指定外</p>
<p>部命令的命令行信息(含路径信息)；</p>
<p>&nbsp;&nbsp; NUMBER_OF_ARGUMENTS：指定支持的参数个数，默认值为0 即没有参数。每个program 最多能够</p>
<p>支持255 个参数，注意如果PROGRAM_TYPE 设置为PLSQL_BLOCK，那么本参数自动忽略；</p>
<p>&nbsp;&nbsp; ENABLED：指定是否将创建的program 置为有效状态，默认情况下为false。</p>
<p>&nbsp;&nbsp; COMMENTS：这个不用再说了吧，注释信息。</p>
<p>下面实际操作一下看看，PL/SQL 或PROCEDURE 没有挑战(ORACLE 中直接即可调用)，咱们创建一下</p>
<p>program，直接调用操作系统中的ls 命令，操作如下：</p>
<p>SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.CREATE_PROGRAM (</p>
<p>program_name =&gt; 'IPCONFIG',</p>
<p>program_action =&gt; 'C:\WINDOWS\system32\ipconfig.exe',</p>
<p>program_type =&gt; 'EXECUTABLE',</p>
<p>enabled =&gt; TRUE);</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
2.2 管理Programs</p>
<p>CREATE_PROGRAM过程的参数时提到，每个program最多支持255 个参数，要为program 添加参数，可以通过DEFINE_PROGRAM_ARGUMENT 过程。不过在为其添加参数前，要注意program 的NUMBER_OF_ARGUMENTS 指定的数量，如果该值为0，那么为其添加参数时就会报错。</p>
<p>查询创建的program 的信息，可以通过USER_SCHEDULER_PROGRAMS 视图，例如：</p>
<p>SQL&gt; select program_name,program_type,program_action,number_of_arguments,enabled</p>
<p>from user_scheduler_programs;</p>
<p><br />
由于前面创建program 時並未指定NUMBER_OF_ARGUMENTS 的值，因此我们这里需要首先修改该值为</p>
<p>一个非0 值，操作如下：</p>
<p>SQL&gt; exec dbms_scheduler.set_attribute('IPCONFIG','NUMBER_OF_ARGUMENTS',1);</p>
<p>PL/SQL procedure successfully completed.</p>
<p>没错， 操作还是使用DBMS_SCHEDULER.SET_ATTRIBUTE 过程。另外需要注意， program 的NUMBER_OF_ARGUMENTS 参数可是说想改就能改的，正常情况下该处理必须是在program 处于enabled 之前确认完毕，否则会触发ORA-27465 错误，因此要修改program 的参数之前，必须首先确保要修改program 的enabled 状态为false。</p>
<p><br />
那么对于已经处于enabled 状态的program，如何修改其状态属性呢？其实很简单，前面操作jobs 时使用的</p>
<p>DBMS_SCHEDULER.DISABLE 过程还记的吗？没错，该过程对于program 同样好使，并且调用方式也完全一</p>
<p>样，例如：</p>
<p>SQL&gt; exec dbms_scheduler.disable('IPCONFIG');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>另外，如果希望将program 置为enabled 状态，执行DBMS_SCHEDULER.ENABLE 过程即可，这里不再例举。</p>
<p>&nbsp;</p>
<p>接下来，就可以为刚刚创建的IPCONFIG添加路径参数，操作如下：</p>
<p>SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (</p>
<p>program_name =&gt; 'IPCONFIG',</p>
<p>argument_position =&gt; 1,</p>
<p>argument_name =&gt; 'dirpath',</p>
<p>argument_type =&gt; 'VARCHAR2',</p>
<p>default_value =&gt; 'C:\');</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
exec DBMS_SCHEDULER.ENABLE('IPCONFIG');</p>
<p><br />
查询为program 定义的参数，可以通过USER_SCHEDULER_PROGRAM_ARGS 视图，例如：</p>
<p>SQL&gt; select program_name,argument_name,argument_position,argument_type</p>
<p>default_value from user_scheduler_program_args;</p>
<p><br />
删除program 的argument 操作也很简单，使用DROP_PROGRAM_ARGUMENT 过程即可，例如：</p>
<p>SQL&gt; exec dbms_scheduler.drop_program_argument('IPCONFIG','dirpath');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>该过程第一个参数指定program 名称，第二个参数指定定义的argument 名称，当然此处也可以指定argument</p>
<p>的位置，即前例视图返回结果中的ARGUMENT_POSITION 列值。</p>
<p>要删除program 的话就更简单了，使用DROP_PROGRAM 过程即可，例如：</p>
<p>SQL&gt; exec dbms_scheduler.drop_program('IPCONFIG');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>当然啦，删除program 的同时，也会删除该program 对应的所有arguments。</p>
<p><br />
实际上SCHEDULER 中创建job 时，也可以指定执行外部的程序。SCHEDULER 中的Job 更像是之前版本</p>
<p>继承过来的JOBS，只不过10g 中SCHEDULER 管理的JOBS 功能更加强大。Programs 与Jobs 不同的是，Jobs</p>
<p>是定义好的，定时执行的任务，而Programs 则是定义好的，等待被执行的对象。</p>
<p><br />
三、使用Schedules</p>
<p>10g 中新推出的SCHEDULER 可能确实会让很多初接触的朋友感觉晕头晕脑，相比之前的jobs，</p>
<p>SCHEDULER 中新增的概念太多。比如说jobs，仍然可以理解成之前版本中的jobs，不过功能更加强大，比如说program，指的是运行的程序(把要做什么单提出来了)，比如说schedule，我将其翻译为调度，定义执行的</p>
<p>频率或者说周期。</p>
<p><br />
3.1 创建和管理Schedules</p>
<p>Schedule，中文直译的话应该理解成调度，从名字来看，它是一个逻辑实体，就是说当创建了schedule 之后，数据库中就肯定存在这一对象，只不过这一对象是用来描述job 的执行周期。</p>
<p>创建schedule 可以通过DBMS_SCHEDULER.CREATE_SCHEDULE 过程，该过程支持的参数如下：</p>
<p>SQL&gt;desc dbms_scheduler</p>
<p>SQL&gt;desc dbms_scheduler.create_schedule;</p>
<p>Parameter Type Mode Default?</p>
<p>--------------- ------------------------ ---- --------</p>
<p>SCHEDULE_NAME VARCHAR2 IN</p>
<p>START_DATE TIMESTAMP WITH TIME ZONE IN Y</p>
<p>REPEAT_INTERVAL VARCHAR2 IN</p>
<p>END_DATE TIMESTAMP WITH TIME ZONE IN Y</p>
<p>COMMENTS VARCHAR2 IN Y</p>
<p>各参数分别代表含意如下：</p>
<p>&nbsp;&nbsp; SCHEDULE_NAME：指定schedule 名称，注意名称不能重复。</p>
<p>&nbsp;&nbsp; START_DATE：指定该调度的开始时间，可为空，当为空时表示该调度暂不起用。</p>
<p>&nbsp;&nbsp; REPEAT_INTERVAL：指定调度的执行频率或周期。</p>
<p>&nbsp;&nbsp; END_DATE：指定调度的结束时间，可为空，为空时就表示该调度将一直进行。</p>
<p>&nbsp;&nbsp; COMMENTS：注释信息。</p>
<p>这其中，比较有技术含量的是REPEAT_INTERVAL 参数，对于这个参数大家应该不会太陌生，因为前面介</p>
<p>绍Jobs，也曾经提到过同名的参数，Schedules 中的REPEAT_INTERVAL 参数和Jobs 中的REPEAT_INTERVAL</p>
<p>参数功能完全相同，甚至参数格式也一模一样。</p>
<p>REPEAT_INTERVAL 参数的语法结构要复杂的多。其中最重要的是FREQ 和INTERVAL 两个关键字。</p>
<p>&nbsp;&nbsp; FREQ 关键字用来指定间隔的时间周期，可选参数有：YEARLY, MONTHLY, WEEKLY, DAILY,</p>
<p>HOURLY, MINUTELY, and SECONDLY，分别表示年、月、周、日、时、分、秒等单位。</p>
<p>&nbsp;&nbsp; INTERVAL 关键字用来指定间隔的频繁，可指定的值的范围从1-99。</p>
<p>比如说， 当指定REPEAT_INTERVAL=&gt;'FREQ=DAILY;INTERVAL=1';就表示每天执行一次， 如果将</p>
<p>INTERVAL 改为7 就表示每7 天执行一次，效果等同于FREQ=WEEKLY;INTERVAL=1。</p>
<p><br />
下面，创建一个schedule，指定调度为每周一次的频率，执行脚本如下：</p>
<p>SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.CREATE_SCHEDULE (</p>
<p>schedule_name =&gt; 'MySchedule',</p>
<p>start_date =&gt; SYSDATE,</p>
<p>repeat_interval =&gt; 'FREQ=WEEKLY; INTERVAL=1',</p>
<p>comments =&gt; 'Every 1 weeks');</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
查询当前已经创建的schedules，可以通过*_SCHEDULER_SCHEDULES 视图(含DBA_,ALL_,USER_)，例如，查看当前用户拥有的schedules，执行语句如下：</p>
<p>SQL&gt; select schedule_name,repeat_interval from user_scheduler_schedules;</p>
<p><br />
如果要修改schedule 属性的话，也是使用DBMS_SCHEDULER.SET_ATTRIBUTE 过程，该过程的调用方式前面已经多次演示过，这里就不再重复举例了，仅说明一点，对于schedule 来说，能够修改的属性包括：</p>
<p>REPEAT_INTERVAL、COMMENTS、END_DATE、START_DATE 以及EVENT_SPEC。</p>
<p><br />
至于删除schedule，再简单不过，执行DBMS_SCHEDULER.DROP_SCHEDULE 过程即可，例如：</p>
<p>SQL&gt; EXEC DBMS_SCHEDULER.DROP_SCHEDULE('MY_FIRST_SCHEDULE');</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
3.2 Schedules调度Programs执行的Jobs</p>
<p>通过schedule 调度program 的执行的job。10g 版本中SCHEDULER 将JOB分成了多个部分，program 负责做什么，schedule 负责啥时候做，job 就简单了，一个字：做。</p>
<p>前面几个小节，已经分别演示了创建管理Jobs，创建管理Programs 以及创建和管理Schedules，下面我</p>
<p>们通过实例来演示，如何创建通过schedule 调度program 的执行的job 吧。</p>
<p><br />
1. 我们用前面创建的Program： IPCONFIG，执行操作系统命令ipconfig。</p>
<p>2. 用我们刚创建的schedule：MySchedule</p>
<p>3. 创建job，按照指定的schedule，执行program，操作如下：</p>
<p>SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.CREATE_JOB (</p>
<p>job_name =&gt; 'ExecCmd',</p>
<p>program_name =&gt; 'IPCONFIG',</p>
<p>schedule_name =&gt; 'MySchedule',</p>
<p>enabled =&gt; true);</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p>创建job 时，start_date,repeat_interval,job_action 等均无须指定，因为这些参数将由program 和schedule 来控</p>
<p>制。</p>
<p><br />
这样，操作完成后，ORACLE 就会自动定时(当前设置为每周执行一次)program 中定义的操作。</p>
<p>要查看当前的执行情况，通过*_scheduler_job_run_details 即可查询(*_scheduler_job_log 也可以，不过该视</p>
<p>图中信息不如detail 中全面)。例如，查看刚刚创建的"ExecCmd"任务的执行情况，执行命令如下：</p>
<p>SQL&gt; select log_id,log_date,status,additional_info from user_scheduler_job_run_details where job_name = 'ExecCmd';</p>
<p><br />
3.3 设置Repeat Interval</p>
<p>Job 和Schedule 中REPEAT_INTERVAL 参数都是用来控制执行的频率或周期，虽然说周期是一个时间性概念，不过REPEAT_INTERVAL 指定的时候并不是一个时间值，而是由一组关键字描述的时间。</p>
<p>除了前面介绍Job 和Schedule 的REPEAT_INTERVAL 参数时，提到该参数拥有FREQ 以及INTERVAL 两个关键字，其实除此之外，还有如BYMONTH、BYWEEKNO、BYYEARDAY、BYDATE 等等参数，可以用来进行更精确的定义，比如通过BYMONTH 关键字指定调度运行的月份，BYDAY 指定调度在哪天运行等等。</p>
<p><br />
REPEAT_INTERVAL 参数的详细语法如下：</p>
<p>repeat_interval = regular_schedule | combined_schedule</p>
<p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p>
<p>regular_schedule = frequency_clause</p>
<p>[";" interval_clause] [";" bymonth_clause] [";" byweekno_clause]</p>
<p>[";" byyearday_clause] [";" bydate_clause] [";" bymonthday_clause]</p>
<p>[";" byday_clause] [";" byhour_clause] [";" byminute_clause]</p>
<p>[";" bysecond_clause] [";" bysetpos_clause] [";" include_clause]</p>
<p>[";" exclude_clause] [";" intersect_clause][";" periods_clause]</p>
<p>[";" byperiod_clause]</p>
<p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p>
<p>combined_schedule = schedule_list [";" include_clause]</p>
<p>[";" exclude_clause] [";" intersect_clause]</p>
<p>frequency_clause = "FREQ" "=" ( predefined_frequency | user_defined_frequency )</p>
<p>predefined_frequency = "YEARLY" | "MONTHLY" | "WEEKLY" | "DAILY" |</p>
<p>"HOURLY" | "MINUTELY" | "SECONDLY"</p>
<p>user_defined_frequency = named_schedule</p>
<p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p>
<p>interval_clause = "INTERVAL" "=" intervalnum</p>
<p>intervalnum = 1 through 99</p>
<p>bymonth_clause = "BYMONTH" "=" monthlist</p>
<p>monthlist = monthday ( "," monthday)*</p>
<p>month = numeric_month | char_month</p>
<p>numeric_month = 1 | 2 | 3 ... 12</p>
<p>char_month = "JAN" | "FEB" | "MAR" | "APR" | "MAY" | "JUN" |</p>
<p>"JUL" | "AUG" | "SEP" | "OCT" | "NOV" | "DEC"</p>
<p>byweekno_clause = "BYWEEKNO" "=" weeknumber_list</p>
<p>weeknumber_list = weeknumber ( "," weeknumber)*</p>
<p>weeknumber = [minus] weekno</p>
<p>weekno = 1 through 53</p>
<p>byyearday_clause = "BYYEARDAY" "=" yearday_list</p>
<p>yearday_list = yearday ( "," yearday)*</p>
<p>yearday = [minus] yeardaynum</p>
<p>yeardaynum = 1 through 366</p>
<p>bydate_clause = "BYDATE" "=" date_list</p>
<p>date_list = date ( "," date)*</p>
<p>date = [YYYY]MMDD [ offset | span ]</p>
<p>bymonthday_clause = "BYMONTHDAY" "=" monthday_list</p>
<p>monthday_list = monthday ( "," monthday)*</p>
<p>monthday = [minus] monthdaynum</p>
<p>monthdaynum = 1 through 31</p>
<p>byday_clause = "BYDAY" "=" byday_list</p>
<p>byday_list = byday ( "," byday)*</p>
<p>byday = [weekdaynum] day</p>
<p>weekdaynum = [minus] daynum</p>
<p>daynum = 1 through 53 /* if frequency is yearly */</p>
<p>daynum = 1 through 5 /* if frequency is monthly */</p>
<p>day = "MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN"</p>
<p>byhour_clause = "BYHOUR" "=" hour_list</p>
<p>hour_list = hour ( "," hour)*</p>
<p>hour = 0 through 23</p>
<p>byminute_clause = "BYMINUTE" "=" minute_list</p>
<p>minute_list = minute ( "," minute)*</p>
<p>minute = 0 through 59</p>
<p>bysecond_clause = "BYSECOND" "=" second_list</p>
<p>second_list = second ( "," second)*</p>
<p>second = 0 through 59</p>
<p>bysetpos_clause = "BYSETPOS" "=" setpos_list</p>
<p>setpos_list = setpos ("," setpos)*</p>
<p>setpos = [minus] setpos_num</p>
<p>setpos_num = 1 through 9999</p>
<p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p>
<p>include_clause = "INCLUDE" "=" schedule_list</p>
<p>exclude_clause = "EXCLUDE" "=" schedule_list</p>
<p>intersect_clause = "INTERSECT" "=" schedule_list</p>
<p>schedule_list = schedule_clause ("," schedule_clause)*</p>
<p>schedule_clause = named_schedule [ offset ]</p>
<p>named_schedule = [schema "."] schedule</p>
<p>periods_clause = "PERIODS" "=" periodnum</p>
<p>byperiod_clause = "BYPERIOD" "=" period_list</p>
<p>period_list = periodnum ("," periodnum)*</p>
<p>periodnum = 1 through 100</p>
<p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p>
<p>offset = ("+" | "-") ["OFFSET:"] duration_val</p>
<p>span = ("+" | "-" | "^") "SPAN:" duration_val</p>
<p>duration_val = dur-weeks | dur_days</p>
<p>dur_weeks = numofweeks "W"</p>
<p>dur_days = numofdays "D"</p>
<p>numofweeks = 1 through 53</p>
<p>numofdays = 1 through 376</p>
<p>minus = "-"</p>
<p>这个语法形式看起来复杂无比，其实实用起来很简单，之所以看起来复杂，是因为其功能太过灵活。</p>
<p><br />
例如：设置任务仅在周5 的时候运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=DAILY; BYDAY=FRI';</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=WEEKLY; BYDAY=FRI';</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=YEARLY; BYDAY=FRI';</p>
<p>上述三条语句虽然指定的关键字小有差异，不过功能相同。</p>
<p>设置任务隔一周运行一次，并且仅在周5 运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=WEEKLY; INTERVAL=2; BYDAY=FRI';</p>
<p>设置任务在当月最后一天运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=MONTHLY; BYMONTHDAY=-1';</p>
<p>设置任务在3 月10 日运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=YEARLY; BYMONTH=MAR; BYMONTHDAY=10';</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=YEARLY; BYDATE=0310';</p>
<p>上述两条语句功能相同。</p>
<p>设置任务每10 隔天运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=DAILY; INTERVAL=10';</p>
<p>设置任务在每天的下午4、5、6 点时运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=DAILY; BYHOUR=16,17,18';</p>
<p>设置任务在每月29 日运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=MONTHLY; BYMONTHDAY=29';</p>
<p>设置任务在每年的最后一个周5 运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=YEARLY; BYDAY=-1FRI';</p>
<p>设置任务每隔50 个小时运行：</p>
<p>REPEAT_INTERVAL =&gt; 'FREQ=HOURLY; INTERVAL=50';</p>
<p>另外，你是否在怀念常规job 中设置interval 的简便，虽然功能较弱，但是设置操作非常简单，无须懊恼，</p>
<p>其实SCHEDULER 中的REPEAT_INTERVAL 也完全可以按照那种方式设置，前面都说了，REPEAT_INTERVAL</p>
<p>实际上是指定周期，直接指定一个时间值，当然也是周期喽。</p>
<p>比如说，设置任务每天执行一次，也可以设置REPEAT_INTERVAL 参数值如下：</p>
<p>REPEAT_INTERVAL =&gt; 'trunc(sysdate)+1'</p>
<p>又比如设置任务每周执行一次：</p>
<p>REPEAT_INTERVAL =&gt; 'trunc(sysdate)+7'、</p>
<p><br />
不过需要注意，这种方式仅用于创建SCHEDULER 中jobs 时使用，不能用于schedule。</p>
<p><br />
四、使用Events</p>
<p>Event 直译对应的中文解释是指事件，不过单纯讲事件毕竟太抽象了，举个示例来形容吧。A(对应某个应用</p>
<p>程序，或者是ORACLE 中的进程)在干活时突然眉头一皱说道，不好，前方有情况，这可怎么办！这时，只见</p>
<p>它认真想了想，过了一会儿脸上一喜说道：有了，俗话说早请示啊晚汇报，出现情况要找领导，赶紧给领导发</p>
<p>消息呗！于是B(也是对应某个应用或ORACLE 进程)就收到了一条A 发过来的"前方有XX 情况"的消息，这个</p>
<p>过程就叫EVENT(含A 发消息以及B 接收消息)。</p>
<p>SCHEDULER 中有两种触发EVENT 的情况：</p>
<p>&nbsp;&nbsp; Scheduler 触发的Events</p>
<p>Scheduler 中触发的Events，一般是说当前schduler 中job 的状态发生修改，类似job 启动，或者运行结束，或者达到运行时间等诸如此类的动作，都能够抛出一个EVENT，接收到EVENT 的applicate 就可以根据这些信息进行适当的处理。</p>
<p>比如说，由于系统太过于繁忙，超出job 启动时间后30 分钟，job 仍然没能顺利启动，那么这个时候，Scheduler 就可以抛出一条EVENT 给外部的应用，以便外部应用能够及时通知DBA，进行处理。</p>
<p>&nbsp;&nbsp; application 触发的Events</p>
<p>外部的应用也可以触发Events，并且由Scheduler 来接收并处理这一类型的Events。所谓Scheduler 处理EVENT 就是指Scheduler 启动相应的job 来执行相关操作，这类job 在创建时专门声明了event 的处理，这样当接收到EVENT 时，这类job 就会启动。</p>
<p>Scheduler 使用Oracle 高级队列来抛出以及销毁Events。当抛出Schduler 触发的Events 时，Scheduler 将消息入队到默认的event 队列，application 则通过检查该队列来处理Events。当抛出application 触发的Events 时，application 将消息入队到处理job 对应的队列中。</p>
<p><br />
下面我们也按照这两个类型来介绍Scheduler 中的Events。</p>
<p><br />
4.1 Scheduler抛出的Events</p>
<p>前面说了，Scheduler 抛出的Events 一般是指job 状态改变时触发的，那么是不是说只要job 状态发生了改变，就会触发Events，其实并非如此，因为默认情况下，job 是不触发Events 的。</p>
<p>Scheduler 中的job 有一个属性叫raise_events，专门用来设置job 触发Events 的条件，该属性在CREATE_JOB时不能执行，因此默认情况下该属性不会赋值，自然也就不会触发EVENT。要设置raise_events 属性，只能是在job 创建完成后，通过SET_ATTRIBUTE 过程修改job 的raise_events 属性。</p>
<p>例如，修改前面创建的job-，启用raise_events 属性，执行语句如下：</p>
<p>SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.SET_ATTRIBUTE('JOBTEST', 'raise_events',DBMS_SCHEDULER.JOB_ALL_EVENTS);</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
上述示例中指定的raise_events 属性的属性值DBMS_SCHEDULER.JOB_ALL_EVENTS，就是抛出Events的触发条件。</p>
<p>触发Events 的有下列的类型，分别代表不同的操作：</p>
<p>&nbsp;&nbsp; job_started：JOB 启动；</p>
<p>&nbsp;&nbsp; job_succeeded：JOB 成功结束；</p>
<p>&nbsp;&nbsp; job_failed：JOB 执行失败；</p>
<p>&nbsp;&nbsp; job_broken：JOB 被置为BROKEN 状态；</p>
<p>&nbsp;&nbsp; job_completed：JOB 达到最大运行次数，或者运行的结束日期；</p>
<p>&nbsp;&nbsp; job_stopped：JOB 被STOP_JOB 过程置为停止执行的状态；</p>
<p>&nbsp;&nbsp; job_sch_lim_reached：Job 的schedule 达到限定值；</p>
<p>&nbsp;&nbsp; job_disabled：JOB 被置于DISABLE 状态；</p>
<p>&nbsp;&nbsp; job_chain_stalled：运行于chain 的JOB 被置于CHAIN_STALLED 状态；</p>
<p>&nbsp;&nbsp; job_all_events：含上述提到的所有类型；</p>
<p>&nbsp;&nbsp; job_run_completed：由于Job 运行出错、成功结束或被手动停止。</p>
<p><br />
起用raise_events 后，Scheduler 就会按照设定的触发条件，当达到触发条件时，即会抛出事件信息到SYS.SCHEDULER$_EVENT_QUEUE 队列。</p>
<p>例如，手动执行一次JOBTEST，看看是否向队列中记录信息，操作如下：</p>
<p>SQL&gt; exec dbms_scheduler.run_job('JOBTEST');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>执行下列脚本，出队数据：</p>
<p>SQL&gt; set serveroutput on</p>
<p>SQL&gt; DECLARE</p>
<p>l_dequeue_options DBMS_AQ.dequeue_options_t;</p>
<p>l_message_properties DBMS_AQ.message_properties_t;</p>
<p>l_message_handle RAW(16);</p>
<p>l_queue_msg sys.scheduler$_event_info;</p>
<p>BEGIN</p>
<p>l_dequeue_options.consumer_name := 'TEST';</p>
<p><br />
DBMS_AQ.dequeue(queue_name =&gt; 'SYS.SCHEDULER$_EVENT_QUEUE',</p>
<p>dequeue_options =&gt; l_dequeue_options,</p>
<p>message_properties =&gt; l_message_properties,</p>
<p>payload =&gt; l_queue_msg,</p>
<p>msgid =&gt; l_message_handle);</p>
<p>COMMIT;</p>
<p><br />
DBMS_OUTPUT.put_line('event_type : ' || l_queue_msg.event_type);</p>
<p>DBMS_OUTPUT.put_line('object_owner : ' || l_queue_msg.object_owner);</p>
<p>DBMS_OUTPUT.put_line('object_name : ' || l_queue_msg.object_name);</p>
<p>DBMS_OUTPUT.put_line('event_timestamp: ' || l_queue_msg.event_timestamp);</p>
<p>DBMS_OUTPUT.put_line('error_code : ' || l_queue_msg.error_code);</p>
<p>DBMS_OUTPUT.put_line('event_status : ' || l_queue_msg.event_status);</p>
<p>DBMS_OUTPUT.put_line('log_id : ' || l_queue_msg.log_id);</p>
<p>DBMS_OUTPUT.put_line('run_count : ' || l_queue_msg.run_count);</p>
<p>DBMS_OUTPUT.put_line('failure_count : ' || l_queue_msg.failure_count);</p>
<p>DBMS_OUTPUT.put_line('retry_count : ' || l_queue_msg.retry_count);</p>
<p>END;</p>
<p>/</p>
<p>event_type : JOB_STARTED</p>
<p>object_owner : TEST</p>
<p>object_name : INSERT_TEST_TBL</p>
<p>event_timestamp: 25-AUG-09 12.49.29.558758 PM +08:00</p>
<p>error_code : 0</p>
<p>event_status : 1</p>
<p>log_id :</p>
<p>run_count : 1</p>
<p>failure_count : 0</p>
<p>retry_count : 0</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
从返回的信息可以看到，event 的类型为JOB_STARTED，表示JOB 启动。实际上job:JOBTEST执行一次至少会向队列中插入两条event 信息，一条为JOB_STARTED，一条则为JOB_SUCCEEDED(也可能是JOB_FAILED)，这里不详细演示，感兴趣的朋友不妨自行测试。</p>
<p>提示：SYS.SCHEDULER$_EVENT_QUEUE 队列基于SYS.SCHEDULER$_EVENT_QTAB 队列表，因此查询</p>
<p>SYS.SCHEDULER$_EVENT_QTAB 也可以获取上述的信息。</p>
<p>SYS.SCHEDULER$_EVENT_QUEUE 是一个固定队列，实际应用的过程中，DBA 应该根据实际情况，将该表访问权限授予相关用户，以便顺利出队该队列中的events 信息。</p>
<p>另外，友情提醒，默认情况下Scheduler 仅保留最近24 小时的Events 信息，如果希望修改该设置的话，可</p>
<p>以通过SET_SCHEDULER_ATTRIBUTE 过程，修改scheduler 的event_expiry_time 属性，该项属性的属性值以</p>
<p>秒为单位。</p>
<p><br />
4.2 Application抛出的Events</p>
<p>首先要说明，这里所说的Application 是个代词，即可以表示ORACLE 数据库之外的应用程序，也可以是ORACLE 数据库中的PROCEDURE 等对象，总之你就将其理解成用户自己创建的对象就好了。</p>
<p>Scheduler 能够抛出Events 让外部应用处理，外部的应用也可以抛出Events 让Scheduler 启动job 处理，不过并不是任何job 都能够对外部应用抛出的Events 做出响应，必须在创建jobs 时明确指定响应的事件。那么如何指定呢？依靠下列两个附加的参数：</p>
<p>&nbsp; queue_spec：指定外部应用抛出的events 消息入队的队列名；</p>
<p>&nbsp; event_condition：指定触发job 启动的条件，这一参数的参数值在设置时应当基于事件消息的自身属性，因为事件消息在入队时，消息的属性都是由application 定义的，因此在设置触发条件时，也应该根据这些属性值就行设置。</p>
<p><br />
下面，我们就演示创建一个由event 触发启动的job，在此之前，首先需要进行一些准备工具，比如创建队列，由于队列需要基于一个队列表，因此在创建队列之前，首先要创建一个队列表，考虑到队列表需要依赖一个对象类型，因此在创建队列表之前，先得创建一个type.......复杂，具体的操作步骤如下：</p>
<p>SQL&gt; create or replace type Test_type1 as object</p>
<p>2 (</p>
<p>3 event_type VARCHAR2(10),</p>
<p>4 object_owner VARCHAR2(30),</p>
<p>5 object_name VARCHAR2(30)</p>
<p>6 );</p>
<p>7 /</p>
<p>Type created.</p>
<p>SQL&gt; begin</p>
<p>2 dbms_aqadm.create_queue_table(</p>
<p>3 queue_table =&gt; 'my_queue_tbl1',</p>
<p>4 queue_payload_type =&gt; 'Test_type1',</p>
<p>5 multiple_consumers =&gt; true);</p>
<p>6 end;</p>
<p>7 /</p>
<p>PL/SQL procedure successfully completed.</p>
<p>SQL&gt; begin</p>
<p>2 dbms_aqadm.create_queue(</p>
<p>3 queue_name =&gt; 'event_t1',</p>
<p>4 queue_table =&gt; 'my_queue_tbl1');</p>
<p>5 end;</p>
<p>6 /</p>
<p>PL/SQL procedure successfully completed.</p>
<p>OK,准备工作完成，下面就来创建一个event 触发启动的job，创建脚本如下：</p>
<p>SQL&gt; BEGIN</p>
<p>2 DBMS_SCHEDULER.CREATE_JOB (</p>
<p>3 job_name =&gt; 'EVENT_JOB_T1',</p>
<p>4 job_type =&gt; 'STORED_PROCEDURE',</p>
<p>5 job_action =&gt; 'SYSTEM.IT',</p>
<p>6 event_condition =&gt; 'tab.user_data.event_type = ''OP_INSERT''',</p>
<p>7 queue_spec =&gt; 'EVENT_T1',</p>
<p>8 enabled =&gt; TRUE);</p>
<p>9 END;</p>
<p>10 /</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
上述脚本仅做演示，因此创建的job 仍然执行IT 过程。</p>
<p><br />
通过pl/sql 直接向event_t1 队列中添加消息的方式，触发job 的启动，具体操作如下。</p>
<p>首先要执行DBMS_AQADM.START_QUEUE 过程，将event_t1 置于允许入队和出队状态(默认情况下创建的队列是不允许出队和入队操作的)，脚本如下：</p>
<p>SQL&gt; exec dbms_aqadm.start_queue(queue_name =&gt; 'event_t1',enqueue =&gt; true,dequeue =&gt; true);</p>
<p>PL/SQL procedure successfully completed.</p>
<p>执行入队操作：</p>
<p>SQL&gt; declare</p>
<p>v_Message Test_type1;</p>
<p>v_EnqueueOptions dbms_aq.enqueue_options_t;</p>
<p>v_MessageProperties dbms_aq.message_properties_t;</p>
<p>v_msg_handle raw(16);</p>
<p>begin</p>
<p>v_message := jss_type1('OP_SELECT', user, 'tmpObj');</p>
<p>dbms_aq.enqueue(queue_name =&gt; 'event_t1',</p>
<p>enqueue_options =&gt; v_enqueueOptions,</p>
<p>message_properties =&gt; v_messageproperties,</p>
<p>payload =&gt; v_message,</p>
<p>msgid =&gt; v_msg_handle);</p>
<p>commit;</p>
<p>end;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
查询队列表中的数据：</p>
<p>SQL&gt; select user_data from my_queue_tbl1;</p>
<p>USER_DATA(EVENT_TYPE, OBJECT_OWNER, OBJECT_NAME)</p>
<p>---------------------------------------------------------</p>
<p>JSS_TYPE1('OP_SELECT', 'TEST', 'tmpObj')</p>
<p>然后查询job</p>
<p>SQL&gt; select to_char(created,'yyyy-mm-dd hh24:mi:ss') from jss_1;</p>
<p>TO_CHAR(CREATED,'YY</p>
<p>-------------------</p>
<p>2009-08-25 12:49:29</p>
<p>看起来jss_1 表中并未有新增加记录，似乎job 没有执行啊。这很正常，还记得咱们创建job 时指定的event_condition 条件吗：</p>
<p><br />
6 event_condition =&gt; 'tab.user_data.event_type = ''OP_INSERT''',</p>
<p>没错，只有当event_type 为'OP_INSERT'时才会触发job 的执行，前面入队时指定的是OP_SELECT，当然</p>
<p>没有触发job 中指定的procedure 啦，下面再次执行入队操作：</p>
<p>SQL&gt; declare</p>
<p>v_Message jss_type1;</p>
<p>v_EnqueueOptions dbms_aq.enqueue_options_t;</p>
<p>v_MessageProperties dbms_aq.message_properties_t;</p>
<p>v_msg_handle raw(16);</p>
<p>begin</p>
<p>v_message := jss_type1('OP_INSERT', user, 'tmpObj');</p>
<p>dbms_aq.enqueue(queue_name =&gt; 'event_t1',</p>
<p>enqueue_options =&gt; v_enqueueOptions,</p>
<p>message_properties =&gt; v_messageproperties,</p>
<p>payload =&gt; v_message,</p>
<p>msgid =&gt; v_msg_handle);</p>
<p>commit;</p>
<p><br />
end;</p>
<p>/</p>
<p>再次查看jss_1 表看看：</p>
<p>SQL&gt; select to_char(created,'yyyy-mm-dd hh24:mi:ss') from jss_1;</p>
<p>TO_CHAR(CREATED,'YY</p>
<p>-------------------</p>
<p>2009-08-25 12:49:29</p>
<p>2009-08-25 13:21:21</p>
<p>多了一条记录，说明job 已经被自动触发。</p>
<p>最后再补充一句，基于event 的job 不能通过DBMS_SCHEDULER.RUN_JOB 过程执行，否则会触发ORA-00942: table or view does not exist 错误。</p>
<p><br />
五、使用Chains</p>
<p>CHAIN(注意不要敲成CHINA) 可以被视做一组Programs 的复合，举个简单的例子：运行PROGRAM:A 以及PROGRAM:B，如果成功的话继续运行PROGRAM:C，否则的话运行PROGRAM:D。Programs:A、B、C、D 以及执行的逻辑关系就构成了一个最简单的CHAIN。</p>
<p>关于CHAIN 的管理操作比较多，比如创建/删除/修改Chains，添加/修改/删除Chain Steps 等等。</p>
<p>5.1 创建Chains</p>
<p>5.1.1 创建CHAIN对象</p>
<p>创建CHAIN 使用DBMS_SCHEDULER.CREATE_CHAIN 过程，这个过程调用非常简单，因为需要指定的</p>
<p>参数极少，该过程的定义如下：</p>
<p>SQL&gt; desc dbms_scheduler.create_chain;</p>
<p>Parameter Type Mode Default?</p>
<p>------------------- ---------------------- ---- --------</p>
<p>CHAIN_NAME VARCHAR2 IN</p>
<p>RULE_SET_NAME VARCHAR2 IN Y</p>
<p>EVALUATION_INTERVAL INTERVAL DAY TO SECOND IN Y</p>
<p>COMMENTS VARCHAR2 IN Y</p>
<p>在创建时，甚至可以简单到只指定一个CHAIN 的名称，其它均为空即可，例如：</p>
<p>SQL&gt; exec dbms_scheduler.create_chain('my_chain1');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>定义好的Chains，可以通过*_SCHEDULER_CHAINS 视图查看，例如：</p>
<p>SQL&gt; select chain_name from user_scheduler_chains;</p>
<p>CHAIN_NAME</p>
<p>------------------------------</p>
<p>MY_CHAIN1</p>
<p>注意，不是说创建了CHAIN 就齐活，只有一个CHAIN 对象ORACLE 还是啥也干不了(当然啦，相信从上面执行的创建语句大家也看出来了)，CHAIN 对象创建之后，要做的工作其实才刚刚开始。其后，还需要定义ChainSteps 以及Chain rules。</p>
<p>5.1.2 创建Chain Step</p>
<p>Chain Steps 就是用来指定CHAIN 执行的操作及执行步骤， 创建CHAIN STEP 是通过</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_STEP 过程进行，例如，为刚刚创建的my_chain1 添加一个step，执行操作如下：</p>
<p>SQL&gt; begin</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_STEP (</p>
<p>chain_name =&gt; 'my_chain1',</p>
<p>step_name =&gt; 'my_step1',</p>
<p>program_name =&gt; 'p_p1');</p>
<p>end;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p>Chain Steps 即可以调用PROGRAM(注意是program，不是procedure，当然program 中可以定义执行procedure)，也可以调用EVENT，甚至调用其它CHAIN(这就叫嵌套CHAIN)。</p>
<p>下面接着为my_chain1 添加两个step，操作如下：</p>
<p>SQL&gt; begin</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_STEP (</p>
<p>chain_name =&gt; 'my_chain1',</p>
<p>step_name =&gt; 'my_step2',</p>
<p>program_name =&gt; 'p_p2');</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_STEP (</p>
<p>chain_name =&gt; 'my_chain1',</p>
<p>step_name =&gt; 'my_step3',</p>
<p>program_name =&gt; 'p_p3');</p>
<p>end;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p>要查询定义的Chain Steps，则是通过*_SCHEDULER_CHAIN_STEPS 视图，例如：</p>
<p>SQL&gt; select chain_name,step_name,program_name from user_scheduler_chain_steps;</p>
<p>CHAIN_NAME STEP_NAME PROGRAM_NAME</p>
<p>-------------------- -------------------- --------------------</p>
<p>MY_CHAIN1 MY_STEP1 P_P1</p>
<p>MY_CHAIN1 MY_STEP2 P_P2</p>
<p>MY_CHAIN1 MY_STEP3 P_P3</p>
<p><br />
5.1.3 创建Chain Rule</p>
<p>接下来，要为CHAIN 的运行定义规则。定义规则是使用DBMS_SCHEDULER.DEFINE_CHAIN_RULE 过程，Chain Rules 依赖于Chain Steps，每个CHAIN RULE 都拥有condition 和action 属性，当满足condition 时则执行action 中指定的step。</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_RULE 过程的语法如下：</p>
<p>SQL&gt; desc dbms_scheduler.define_chain_rule;</p>
<p>Parameter Type Mode Default?</p>
<p>---------- -------- ---- --------</p>
<p>CHAIN_NAME VARCHAR2 IN</p>
<p>CONDITION VARCHAR2 IN</p>
<p>ACTION VARCHAR2 IN</p>
<p>RULE_NAME VARCHAR2 IN Y</p>
<p>COMMENTS VARCHAR2 IN Y</p>
<p>CHAIN_NAME 就不说了，需要注意的是CONDITION 和ACTION 两个参数。在为condition 参数指定值时，其语法看起来稍稍复杂一些，或者说是灵活，condition 参数值支持下列的语法形式：</p>
<p>TRUE</p>
<p>FALSE</p>
<p>stepname [NOT] SUCCEEDED</p>
<p>stepname [NOT] FAILED</p>
<p>stepname [NOT] STOPPED</p>
<p>stepname [NOT] COMPLETED</p>
<p>stepname ERROR_CODE IN (integer, integer, integer ...)</p>
<p>stepname ERROR_CODE NOT IN (integer, integer, integer ...)</p>
<p>stepname ERROR_CODE = integer</p>
<p>stepname ERROR_CODE != integer</p>
<p>stepname ERROR_CODE &lt;&gt; integer</p>
<p>stepname ERROR_CODE &gt; integer</p>
<p>stepname ERROR_CODE &gt;= integer</p>
<p>stepname ERROR_CODE &lt; integer</p>
<p>stepname ERROR_CODE &lt;= integer</p>
<p>甚至于，还可以制定成下列逻辑语法：</p>
<p>expression AND expression</p>
<p>expression OR expression</p>
<p>NOT (expression)</p>
<p>比如说，我们希望条件为step1 成功运行，那么可以指定condition 参数值如下：</p>
<p>'step1 completed'</p>
<p>Action 参数相对简单一些，这个参数用来指定当满足condition 参数时，CHAIN 执行的操作。</p>
<p>例如，创建CHAIN RULE，首先执行my_step1，如果my_step1 成功执行的话，就继续执行my_step2，如</p>
<p>果my_step2 也成功执行的话，则结束该CHAIN，创建脚本如下：</p>
<p>SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_RULE (</p>
<p>chain_name =&gt; 'my_chain1',</p>
<p>condition =&gt; 'TRUE',</p>
<p>action =&gt; 'START my_step1',</p>
<p>rule_name =&gt; 'my_rule1');</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_RULE (</p>
<p>chain_name =&gt; 'my_chain1',</p>
<p>condition =&gt; 'my_step1 completed',</p>
<p>action =&gt; 'START my_step2',</p>
<p>rule_name =&gt; 'my_rule2');</p>
<p>DBMS_SCHEDULER.DEFINE_CHAIN_RULE (</p>
<p>chain_name =&gt; 'my_chain1',</p>
<p>condition =&gt; 'my_step2 completed',</p>
<p>action =&gt; 'end 0',</p>
<p>rule_name =&gt; 'my_rule3');</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
5.1.4 运行Chains</p>
<p>最后，来运行一下创建的my_chain1 吧，手动运行CHAIN 是通过DBMS_SCHEDULER.RUN_CHAIN 过程，</p>
<p>例如：</p>
<p>SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.RUN_CHAIN (</p>
<p>chain_name =&gt; 'my_chain1',</p>
<p>start_steps =&gt; 'my_step1');</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p>语句执行成功，下面需要查看一下执行的结果。我们之前定义的p_p1 等program 对象，实际上是调用procedure，向一个指定表jss_t2 中插入记录，这里直接查询一下该表，就知道执行情况了(在此之前，jss_t2 表为空)：</p>
<p>SQL&gt; select * from jss_t2;</p>
<p>TP DT</p>
<p>------------------------------ ------------</p>
<p>p_p1 inserted 03-SEP-09</p>
<p>p_p2 inserted 03-SEP-09</p>
<p>你看，jss_t2 表中有了两条记录，对应前面设置的CHAIN RULE，说明my_step1 和my_step2 均已正确执行。提示：Chains 在执行前，必须被置于enabled 状态，默认情况下刚刚创建的CHAIN 都是disabled 状态，要修改Chains 的状态，还是通过DBMS_SCHEDULER.ENABLE 和DBMS_SCHEDULER.DISABLE 两过程，这里就不演示了。手动执行的CHAIN 的话没有系统级的日志记录，因此如果希望看到详细执行情况的话，建议创建job 来执行CHAIN，例如：</p>
<p><br />
SQL&gt; BEGIN</p>
<p>DBMS_SCHEDULER.CREATE_JOB (</p>
<p>job_name =&gt; 'chain_job_1',</p>
<p>job_type =&gt; 'CHAIN',</p>
<p>job_action =&gt; 'my_chain1',</p>
<p>repeat_interval =&gt; 'freq=daily;interval=1',</p>
<p>enabled =&gt; TRUE);</p>
<p>END;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p>然后，dba 就可以通过定期观察*_scheduler_job_run_details 视图来确认chain 的执行情况了。</p>
<p><br />
5.2 管理Chains</p>
<p>5.2.1 修改Chains属性</p>
<p>基本上碰到修改CHAIN 属性的机率不会太大，因此确实没啥可修改的，对于CHAIN 对象来说，能够修改的属性只有两个：evaluation_interval 和comments，这两个参数一般情况下甚至都不会进行设置。如果你碰到了确实需要修改的情况，没问题，DBMS_SCHEDULER.SET_ATTRIBUTE 过程还记的吧，没错，修改CHAIN 也是用它。例如：</p>
<p>SQL&gt; select chain_name,comments from user_scheduler_chains;</p>
<p>CHAIN_NAME COMMENTS</p>
<p>-------------------- --------------------------</p>
<p>MY_CHAIN1</p>
<p>SQL&gt; exec dbms_scheduler.set_attribute('my_chain1','comments','change it for a test!');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>SQL&gt; select chain_name,comments from user_scheduler_chains;</p>
<p>CHAIN_NAME COMMENTS</p>
<p>-------------------- --------------------------</p>
<p>MY_CHAIN1 change it for a test !</p>
<p><br />
5.2.2 设置Chain Step运行属性</p>
<p>修改Chain Step 的运行属性就不能使用DBMS_SCHEDULER.SET_ATTRIBUTE 了，而是有专门的过程</p>
<p>DBMS_SCHEDULER.ALTER_CHAIN 处理，该过程的定义如下：</p>
<p>SQL&gt; desc dbms_scheduler.alter_chain;</p>
<p>Parameter Type Mode Default?</p>
<p>---------- -------- ---- --------</p>
<p>CHAIN_NAME VARCHAR2 IN</p>
<p>STEP_NAME VARCHAR2 IN</p>
<p>ATTRIBUTE VARCHAR2 IN</p>
<p>VALUE BOOLEAN IN</p>
<p>前两个参数就不说了，ATTRIBUTE 参数用来指定STEP 的属性值，可设定的属性值有3 个，每个属性值都</p>
<p>有TRUE 和FALSE 两个选项，由VALUE 参数指定：</p>
<p>&nbsp;&nbsp; PAUSE：设置该参数值为TRUE 时，当step 运行时，其运行状态就会变更为PAUSED；</p>
<p>&nbsp;&nbsp; SKIP：设置该参数值为TRUE 时，当step 满足运行条件时，并不是执行step 中的program，而是直接跳过，注意当SKIP 参数值设置为TRUE，并且PAUSE 参数值也被设置为TRUE，那么将会以PAUSE 的状态优先；</p>
<p>&nbsp;&nbsp; RESTART_ON_RECOVERY：设置该参数值为TRUE 时，如果由于数据库shutdown 导致step 被停止，那么当下次数据库启动时，step 会自动重新运行。</p>
<p>DBMS_SCHEDULER.ALTER_CHAIN 过程修改Chain Step 属性后，只有当下次运行时才会生效，如果要修改当前运行中Chain Step 的属性，也有一个专门的过程DBMS_SCHEDULER.ALTER_RUNNING_CHAIN 进行处理，该过程语法与DBMS_SCHEDULER.ALTER_CHAIN 一模一样，这里就不详细介绍了。</p>
<p><br />
5.2.3 删除Chain Rules</p>
<p>Chain Rules 没有对应的修改方法，如果要修改某个Chain 的rule，只能首先删除不适当的rule，然后重新添加新rule(所谓添加，其实就是再重新定义一个rule)。</p>
<p>删除Chain Rule 有专门的过程DBMS_SCHEDULER.DROP_CHAIN_RULE，该过程语法如下：</p>
<p>SQL&gt; desc dbms_scheduler.drop_chain_rule;</p>
<p>Parameter Type Mode Default?</p>
<p>---------- -------- ---- --------</p>
<p>CHAIN_NAME VARCHAR2 IN</p>
<p>RULE_NAME VARCHAR2 IN</p>
<p>FORCE BOOLEAN IN Y</p>
<p>举个简单的示例，比如删除前面定义的my_rule3，执行过程如下：</p>
<p>SQL&gt; exec dbms_scheduler.drop_chain_rule('my_chain1','my_rule3',true);</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
5.2.4 删除Chain Steps</p>
<p>删除Chain Step 也有专门的过程DBMS_SCHEDULER.DROP_CHAIN_STEP 进行处理，该过程语法如下：</p>
<p>SQL&gt; desc dbms_scheduler.drop_chain_step;</p>
<p>Parameter Type Mode Default?</p>
<p>---------- -------- ---- --------</p>
<p>CHAIN_NAME VARCHAR2 IN</p>
<p>STEP_NAME VARCHAR2 IN</p>
<p>FORCE BOOLEAN IN Y</p>
<p>看着有点儿眼熟是吧，没错，与drop_chain_rule 的相似度高达90%以上。例如，删除之前定义的my_step3，</p>
<p>执行过程如下：</p>
<p>SQL&gt; exec dbms_scheduler.drop_chain_step('my_chain1','my_step3',true);</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
5.2.5 删除Chains</p>
<p>如果要删除Chain 那就更简单了，执行dbms_scheduler.drop_chain 过程即可，例如：</p>
<p>SQL&gt; exec dbms_scheduler.drop_chain('my_chain1',true);</p>
<p>PL/SQL procedure successfully completed.</p>
<p>注意，执行drop_chain 时，如果不指定force 参数为TRUE，那么默认情况下ORACLE 会首先检查要删除的CHAIN 是否还有被依赖的对象，如果存在的话，会报ORA-27479 错误，提示仍然有依赖的对象(所谓依赖的对象就是指，该chain 仍然存在chain_step 或chain_rule 之类)，因此无法直接删除。这种情况下解决方案有两种：</p>
<p>一是手动删除所有相关的chain_step 和chain_rule，然后再执行chain 的删除，再就是附加force 参数并指定参数</p>
<p>值为true，这样ORACLE 就会自动替你清除所有依赖的对象了。</p>
<p>&nbsp;</p>
<p>六、使用Job Classes</p>
<p>Job Classes 相当于创建了一个job 组，DBA 可以将那些具有相同特性的job，统统放到相同的Job Classes中，然后通过对Job Class 应用ORACLE 中的"资源使用计划"特性，就可以对这些job 执行过程中所需要的资源分配情况进行管理。</p>
<p>1、创建Job Classes</p>
<p>使用DBMS_SCHEDULER 包的CREATE_JOB_CLASS 过程创建Job Classes，该过程支持的参数如下：</p>
<p>SQL&gt; desc dbms_scheduler.create_job_class;</p>
<p>Parameter Type Mode Default?</p>
<p>----------------------- -------------- ---- --------</p>
<p>JOB_CLASS_NAME VARCHAR2 IN</p>
<p>RESOURCE_CONSUMER_GROUP VARCHAR2 IN Y</p>
<p>SERVICE VARCHAR2 IN Y</p>
<p>LOGGING_LEVEL BINARY_INTEGER IN Y</p>
<p>LOG_HISTORY BINARY_INTEGER IN Y</p>
<p>COMMENTS VARCHAR2 IN Y</p>
<p>其中：</p>
<p>JOB_CLASS_NAME：要创建的Job Class 的名称，注意指定的长度不要超过30 个字符，也不要与现有Job Class 同名；</p>
<p>RESOURCE_CONSUMER_GROUP：指定创建的Job Class 所在的RCG；</p>
<p>提示：啥是Resource Consumer Group</p>
<p>你可以将其理解成一个资源分配的方式，处于相同RCG 组中的用户、会话、或者对象共用一组资源，这组资源中可供分配的资源按照DBA 指定的方式分配给RCG。如果设计合理，通过这种方式，可以更有效的利用服务器的资源。</p>
<p>SERVICE：指定创建的Job Class 所在Service，本选项常见于RAC 环境，我们都知道RAC 环境由多实例+数据库组成，此处所指定的Service 实际就是指Job Class 会在哪个实例上运行。</p>
<p>注意：本参数与RESOURCE_CONSUMER_GROUP 参数相互冲突，同一个Job Class 只同设置两个参数中的一个值。</p>
<p>&nbsp;&nbsp; LOGGING_LEVEL：指定日志记录的级别，有下列三种级别：</p>
<p>&nbsp;&nbsp; DBMS_SCHEDULER.LOGGING_OFF：关闭日志记录功能；</p>
<p>&nbsp;&nbsp; DBMS_SCHEDULER.LOGGING_RUNS：对该Job Class 下所有任务的运行信息进行记录；</p>
<p>&nbsp;&nbsp; DBMS_SCHEDULER.LOGGING_FULL：记录该Job Class 下任务的所有相关信息，不仅有任务的运行情况，甚至连任务的创建、修改等也均将记入日志。</p>
<p>&nbsp;&nbsp; LOG_HISTORY：指定日志记录的时间，以天为单位，比如指定LOG_HISTORY 参数值为90，就表示日志信息保留最近90 天的内容。</p>
<p>&nbsp;&nbsp; COMMENTS：指定注释信息。</p>
<p><br />
上述各个参数，除了LOG_CLASS_NAME 参数为必选参外，其它均为可选参数，例如：</p>
<p>SQL&gt; EXEC DBMS_SCHEDULER.CREATE_JOB_CLASS('my_first_jc');</p>
<p>PL/SQL procedure successfully completed</p>
<p><br />
查询系统中已经存在的Job Classes .可以通过DBA_SCHEDULER_JOB_CLASSES视图( 或ALL_SCHEDULER_JOB_CLASS 视图)</p>
<p><br />
当创建Jobs 时，可以通过JOB_CLASS 参数来指定job 所在的Job Class，如果不指定的话，创建的job 默认属于DEFAULT_JOB_CLASS 。至于说如何查询创建的jobs 属于哪个Job Class ， 还用说吗，*_SCHEDULER_JOBS 视图中的JOB_CLASS 列呗。</p>
<p><br />
2、管理Job Classes</p>
<p>DBMS_SCHEDULER.SET_ATTRIBUTE 过程大家应当还记的，前面的小节中演示中使用该过程，修改job的属性，实际上SET_ATTRIBUTE 也同样可以用来修改Job Class 的属性，操作方法与修改job 属性完全相同，只不过作用函概的范围更广，修改Job Class 后，该Job Class 下属的所有job 属性都会被级联修改(当前正运行的不会立刻生效，将等到下次运行时生效)。</p>
<p><br />
例如：修改刚刚创建的MY_FIRST_JC 的日志保存时间：</p>
<p>SQL&gt; EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('SYS.MY_FIRST_JC','LOG_HISTORY','30');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>提示：Job Class 可被修改的属性，即创建时可选择指定的那5 个属性。</p>
<p><br />
3、删除Job Classes</p>
<p>DBMS_SCHEDULER 包提供了DROP_JOB_CLASS 过程，用来删除Job Classes。该过程调用非常简单，例</p>
<p>如，删除刚刚创建的MY_FIRST_JC，执行命令如下：</p>
<p>JSSWEB&gt; EXEC DBMS_SCHEDULER.DROP_JOB_CLASS('MY_FIRST_JC');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>如果有多个Job Classes 需要删除，并不需要多次执行DROP_JOB_CLASS，只需要在为该过程指定值时，参数值间以逗号分隔即可。</p>
<p>&nbsp;</p>
<p>七、使用Windows</p>
<p>此Windows 非彼Windows，通常说的Windows 是指盖首富的操作系统，而此处所说的Windows，是指SCHEDULER 特性中的一个子项。在SCHEDULER 中，WINDOW 对应的是一个时间窗口的概念。我们知道普通的jobs 是没有运行时间管理地概念的，就是说一个job 启动之后，用户只能被动地等待其执行，一直到其执行地任务完成(或DBA 手动kill 对应进程)，在此期间，执行的job 将与其它活动的进程共同竞争当前系统中的资源。对于大型数据库系统，系统资源那可是相当宝贵的无形资产哪，企能谁说用就用、想什么时候用就什么时候用，没点儿计划没点儿节制这还了得。你还别说，在9i 之前，还真就是这么回事儿，谁想用就用，谁也管不了，其中表示最甚的就是job。你是否想起了Job Classes，没错定义Job Classes 确实可以控制job 能够使用的资源，不过单单使用Job Classes 并不能灵活的控制job 在合适的时间使用适当的资源。进入10g之后，SCHEDULER 中提供了WINDOW，事情终于有了缓解。WINDOW 可以指定一个时间窗口，在此期间，通过与Job Classes 的搭配组合，能够有效控制job 执行时支配(使用)的资源。比如说job 通常是在凌晨服务器负载较低时执行，那么就可以通过WINDOW 设置在此期间，允许jobs 使用更多的系统资源，而到了工作时间后，如果job 仍未执行完成，为其分配另一个有限的资源，以尽可能降低job 执行占用的资源对其它业务的影响。</p>
<p><br />
１、创建Window</p>
<p>创建Window 有一个专门的过程：DBMS_SCHEDULER.CREATE_WINDOW 进行处理，该过程有两种调用方式，如下：</p>
<p>--基于SCHEDULE</p>
<p>DBMS_SCHEDULER.CREATE_WINDOW (</p>
<p>window_name IN VARCHAR2,</p>
<p>resource_plan IN VARCHAR2,</p>
<p>schedule_name IN VARCHAR2,</p>
<p>duration IN INTERVAL DAY TO SECOND,</p>
<p>window_priority IN VARCHAR2 DEFAULT 'LOW',</p>
<p>comments IN VARCHAR2 DEFAULT NULL);</p>
<p>--基于定义的调度</p>
<p>DBMS_SCHEDULER.CREATE_WINDOW (</p>
<p>window_name IN VARCHAR2,</p>
<p>resource_plan IN VARCHAR2,</p>
<p>start_date IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,</p>
<p>repeat_interval IN VARCHAR2,</p>
<p>end_date IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,</p>
<p>duration IN INTERVAL DAY TO SECOND,</p>
<p>window_priority IN VARCHAR2 DEFAULT 'LOW',</p>
<p>comments IN VARCHAR2 DEFAULT NULL);</p>
<p><br />
刨开那些看着眼熟的，已经认识的，看参数名就知道其所代表含义的之外，下列几个参数可能需要关注：</p>
<p>&nbsp;&nbsp; Resource_plan：这一参数用来指定要使用的资源使用计划，当打开WINDOW 时，就会自动按照指定的资源使用计划中的设置分配资源，当WINDOW 关闭时(没错，window 是会关闭的，要不怎么说有效控制资源的使用情况泥)，系统会自动切换回适当资源计划。这个参数在执行过程时甚至可以指定为NULL 或空值''，当设置为NULL 时，就表示使用默认的资源计划，当设置为空值''时，表示禁用资源使用计划。</p>
<p>&nbsp;&nbsp; Duration：指定WINDOW 的有效期，比如说指定为interval '5' hour 就表示5 个小时，该参数在执行过程时必须指定参数值，否则创建会报错。</p>
<p>&nbsp;&nbsp; Window_priority：该参数用来指定WINDOW 的优先级。因为在相同时间只有一个WINDOW 有效，因此如果在创建WINDOW 时发现重叠的情况，ORACLE 就需要根据这一参数指定的规则，来确定优先级，说白了就是先把资源给谁用，这一参数有两个可选值：HIGH 或LOW，默认值为LOW。</p>
<p><br />
正如前面CREATE_WINDOW 过程语法结构显示的那样，调用该过程有两种方式，差异就在于是指定现有定义好的调度SCHEDULE，还是在执行过程时指定调度，目标和实现的功能都是相同的，这里仅做示例，咱就挑个最复杂的方式吧，执行过程时指定调度，执行脚本如下：</p>
<p><br />
SQL&gt; begin</p>
<p>dbms_scheduler.create_window(</p>
<p>window_name =&gt; 'my_first_wd1',</p>
<p>resource_plan =&gt; null,</p>
<p>start_date =&gt; sysdate,</p>
<p>repeat_interval =&gt; 'FREQ=DAILY; INTERVAL=5',</p>
<p>duration =&gt; interval '1' hour);</p>
<p>end;</p>
<p>/</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
查询当前拥有的WINDOW，可以通过*_SCHEDULER_WINDOWS视图(注意只有DBA 和ALL，没有USER，因为所有定义的WINDOW 都属于SYS 用户)。除了*_SCHEDULER_WINDOWS 视图显示当前所有WINDOW外，还有：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; *_SCHEDULER_WINDOW_DETAILS 视图：显示WINDOW 的详细信息；</p>
<p>&nbsp;&nbsp; *_SCHEDULER_WINDOW_LOG 视图：显示WINDOW 的日志，比如打开和关闭；</p>
<p><br />
２、管理Window</p>
<p>通过前面那些SCHEDULER 对象的学习，相当大家已经了解了ORACLE SCHEDULER 中对象的特点，对于多数对象的管理，不外乎下列几种：</p>
<p>修改对象属性，使用SET_ATTRIBUTE 过程；</p>
<p>SQL&gt; exec dbms_scheduler.set_attribute('sys.my_first_wd1','start_date',sysdate+1);</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
ENABLE 对象，使用ENABLE 过程；</p>
<p>SQL&gt; exec dbms_scheduler.enable('sys.my_first_wd1');</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
DISABLE 对象，使用DISABLE 过程；</p>
<p>SQL&gt; exec dbms_scheduler.disable('sys.my_first_wd1');</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
删除对象，使用DROP_WINDOW 过程；</p>
<p>SQL&gt; exec dbms_scheduler.drop_window('sys.my_first_wd1');</p>
<p>PL/SQL procedure successfully completed.</p>
<p><br />
除此之外呢，对于WINDOW 对象来说，由于其特殊作用，又有：手动打开WINDOW，使用OPEN_WINDOW 过程；</p>
<p>注意WINDOW 是依赖于其调度的，因此在手动打开WINDOW 时，必须为其指定duration 属性：</p>
<p>SQL&gt; exec dbms_scheduler.open_window('sys.my_first_wd1',interval '1' hour);;</p>
<p>PL/SQL procedure successfully completed.</p>
<p>&nbsp;&nbsp; 手动关闭WINDOW，使用CLOSE_WINDOW 过程；</p>
<p>SQL&gt; exec dbms_scheduler.close_window('sys.my_first_wd1');</p>
<p>PL/SQL procedure successfully completed.</p>
<p>关闭和打开WINDOW，都会记录日志，大家可以通过*_SCHEDULER_WINDOW_LOG 视图中获取这部分</p>
<p>信息。</p>
<p><br />
３、关于WINDOWGROUP</p>
<p>除了WINDOW 外，还有一个与WINDOW 有关系的叫WINDOW GROUP，一个WINDOW GROUP 可能包含多个WINDOW。使用WINDOW GROUP 的本意是这样的，假如说某个job 执行的时间比较长，甚至全天24小时都在执行，对于这类job，单个WINDOW 很难有效调整其资源占用，这时间呢，就可以通过设置一个WINDOW GROUP，该WINDOW GROUP 中包含了多个WINDOW，每个WINDOW 分别负责不同时间点时的资源使用计划。</p>
<p>然后在创建JOB 时，指定schedule_name 参数为WINDOW GROUP 的名称(想不到SCHEDULE_NAME 还能指定为WINDOW GROUP 哪，其实何止WINDOW GROUP，还可以直接指定成WINDOW 哪)，这样，就可以通过很简单的方式，将job 与window 联系在一起了。</p>
<p><br />
WINDOW GROUP 的创建和管理与前面介绍的方式极其相似：</p>
<p>&nbsp;&nbsp; 创建，使用CREATE_WINDOW_GROUP 过程；</p>
<p>&nbsp;&nbsp; 删除，使用DROP_WINDOW_GROUP 过程；</p>
<p>&nbsp;&nbsp; 添加WINDOW 成员，使用ADD_WINDOW_GROUP_MEMBER 过程；</p>
<p>&nbsp;&nbsp; 删除WINDOW 成员，使用REMOVE_WINDOW_GROUP_MEMBER 过程；</p>
<p>&nbsp;&nbsp; 启用，使用ENABLE 过程；</p>
<p>&nbsp;&nbsp; 禁用，使用DISABLE 过程；</p>
<p>这些过程的调用方式也都非常简单，这里就不着重演示了，感兴趣的朋友不妨自行尝试。</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/tianlesoftware/archive/2009/10/22/4715218.aspx<br />
</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:56 <a href="http://www.blogjava.net/javaex/articles/303645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (12)使用Window和Window Group 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-using-window.shtml</title><link>http://www.blogjava.net/javaex/articles/303635.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303635.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303635.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303635.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303635.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303635.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(12)使用Window和Window Group</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-9-8</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h2>七、使用Windows </h2>
            <p>　　此Windows非彼Windows，通常说的Windows是指盖首富的操作系统，而此处所说的Windows，是指SCHEDULER特性中的一个子项。在SCHEDULER中，WINDOW对应的是一个时间窗口的概念。 </p>
            <p>　　我们知道普通的jobs是没有运行时间管理地概念的，就是说一个job启动之后，用户只能被动地等待其执行，一直到其执行地任务完成(或DBA手动kill对应进程)，在此期间，执行的job将与其它活动的进程共同竞争当前系统中的资源。对于大型数据库系统，系统资源那可是相当宝贵的无形资产哪，企能谁说用就用、想什么时候用就什么时候用，没点儿计划没点儿节制这还了得。你还别说，在9i之前，还真就是这么回事儿，谁想用就用，谁也管不了，其中表示最甚的就是job。你是否想起了Job&nbsp;Classes，没错定义Job&nbsp;Classes确实可以控制job能够使用的资源，不过单单使用Job&nbsp;Classes并不能灵活的控制job在合适的时间使用适当的资源。进入10g之后，SCHEDULER中提供了WINDOW，事情终于有了缓解。 </p>
            <p>　　WINDOW 可以指定一个时间窗口，在此期间，通过与Job&nbsp;Classes的搭配组合，能够有效控制job执行时支配(使用)的资源。比如说job通常是在凌晨服务器负载较低时执行，那么就可以通过WINDOW设置在此期间，允许jobs使用更多的系统资源，而到了工作时间后，如果job仍未执行完成，为其分配另一个有限的资源，以尽可能降低job执行占用的资源对其它业务的影响。 </p>
            <h4>１、创建Window </h4>
            <p>　　创建Window有一个专门的过程：DBMS_SCHEDULER.CREATE_WINDOW进行处理，该过程有两种调用方式，如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>-- 基于SCHEDULE </p>
                <p>DBMS_SCHEDULER.CREATE_WINDOW&nbsp;( </p>
                <p>&nbsp;&nbsp;&nbsp;window_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2, </p>
                <p>&nbsp;&nbsp;&nbsp;resource_plan&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2, </p>
                <p>&nbsp;&nbsp;&nbsp;schedule_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2, </p>
                <p>&nbsp;&nbsp;&nbsp;duration&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;INTERVAL&nbsp;DAY&nbsp;TO&nbsp;SECOND, </p>
                <p>&nbsp;&nbsp;&nbsp;window_priority&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEFAULT&nbsp;&#168;LOW&#168;, </p>
                <p>&nbsp;&nbsp;&nbsp;comments&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEFAULT&nbsp;NULL); </p>
                <p>-- 基于定义的调度 </p>
                <p>DBMS_SCHEDULER.CREATE_WINDOW&nbsp;( </p>
                <p>&nbsp;&nbsp;&nbsp;window_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2, </p>
                <p>&nbsp;&nbsp;&nbsp;resource_plan&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2, </p>
                <p>&nbsp;&nbsp;&nbsp;start_date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;TIMESTAMP&nbsp;WITH&nbsp;TIME&nbsp;ZONE&nbsp;DEFAULT&nbsp;NULL, </p>
                <p>&nbsp;&nbsp;&nbsp;repeat_interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2, </p>
                <p>&nbsp;&nbsp;&nbsp;end_date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;TIMESTAMP&nbsp;WITH&nbsp;TIME&nbsp;ZONE&nbsp;DEFAULT&nbsp;NULL, </p>
                <p>&nbsp;&nbsp;&nbsp;duration&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;INTERVAL&nbsp;DAY&nbsp;TO&nbsp;SECOND, </p>
                <p>&nbsp;&nbsp;&nbsp;window_priority&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEFAULT&nbsp;&#168;LOW&#168;, </p>
                &nbsp;&nbsp;&nbsp;comments&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEFAULT&nbsp;NULL); </ul>
                </div>
                <p>　　刨开那些看着眼熟的，已经认识的，看参数名就知道其所代表含义的之外，下列几个参数可能需要关注： </p>
                <ul>
                    <li>Resource_plan ：这一参数用来指定要使用的资源使用计划，当打开WINDOW时，就会自动按照指定的资源使用计划中的设置分配资源，当WINDOW关闭时(没错，window是会关闭的，要不怎么说有效控制资源的使用情况泥)，系统会自动切换回适当资源计划。这个参数在执行过程时甚至可以指定为NULL或空值&#168;&#168;，当设置为NULL时，就表示使用默认的资源计划，当设置为空值&#168;&#168;时，表示禁用资源使用计划。
                    <li>Duration ：指定WINDOW的有效期，比如说指定为interval&nbsp;&#168;5&#168;&nbsp;hour就表示5个小时，该参数在执行过程时必须指定参数值，否则创建会报错。
                    <li>Window_priority ：该参数用来指定WINDOW的优先级。因为在相同时间只有一个WINDOW有效，因此如果在创建WINDOW时发现重叠的情况，ORACLE就需要根据这一参数指定的规则，来确定优先级，说白了就是先把资源给谁用，这一参数有两个可选值：HIGH或LOW，默认值为LOW。 </li>
                </ul>
                <p>　　正如前面CREATE_WINDOW过程语法结构显示的那样，调用该过程有两种方式，差异就在于是指定现有定义好的调度SCHEDULE，还是在执行过程时指定调度，目标和实现的功能都是相同的，这里仅做示例，咱就挑个最复杂的方式吧，执行过程时指定调度，执行脚本如下： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;begin </p>
                    <p>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;dbms_scheduler.create_window(window_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;my_first_wd1&#168;, </p>
                    <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource_plan&nbsp;&nbsp;&nbsp;=&gt;&nbsp;null, </p>
                    <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;sysdate, </p>
                    <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repeat_interval&nbsp;=&gt;&nbsp;&#168;FREQ=DAILY;&nbsp;INTERVAL=5&#168;, </p>
                    <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;duration&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;interval&nbsp;&#168;1&#168;&nbsp;hour); </p>
                    <p>&nbsp;&nbsp;7&nbsp;&nbsp;end; </p>
                    <p>&nbsp;&nbsp;8&nbsp;&nbsp;/ </p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <p>　　查询当前拥有的WINDOW，可以通过*_SCHEDULER_WINDOWS视图(注意只有DBA和ALL，没有USER，因为所有定义的WINDOW都属于SYS用户)。除了*_SCHEDULER_WINDOWS视图显示当前所有WINDOW外，还有： </p>
                    <ul>
                        <li>*_SCHEDULER_WINDOW_DETAILS 视图：显示WINDOW的详细信息；
                        <li>*_SCHEDULER_WINDOW_LOG 视图：显示WINDOW的日志，比如打开和关闭； </li>
                    </ul>
                    <h4>２、管理Window </h4>
                    <p>　　通过前面那些SCHEDULER对象的学习，相当大家已经了解了ORACLE&nbsp;SCHEDULER中对象的特点，对于多数对象的管理，不外乎下列几种： </p>
                    <ul>
                        <li>修改对象属性，使用SET_ATTRIBUTE过程； </li>
                    </ul>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.set_attribute(&#168;sys.my_first_wd1&#168;,&#168;start_date&#168;,sysdate+1); </p>
                        PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                        </div>
                        <ul>
                            <li>ENABLE 对象，使用ENABLE过程； </li>
                        </ul>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.enable(&#168;sys.my_first_wd1&#168;); </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                            </div>
                            <ul>
                                <li>DISABLE 对象，使用DISABLE过程； </li>
                            </ul>
                            <div class="articleBlockGrey">
                            <ul>
                                <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.disable(&#168;sys.my_first_wd1&#168;); </p>
                                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                </div>
                                <ul>
                                    <li>删除对象，使用DROP_WINDOW过程； </li>
                                </ul>
                                <div class="articleBlockGrey">
                                <ul>
                                    <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.drop_window(&#168;sys.my_first_wd1&#168;); </p>
                                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                    </div>
                                    <p>　　除此之外呢，对于WINDOW对象来说，由于其特殊作用，又有： </p>
                                    <ul>
                                        <li>手动打开WINDOW，使用OPEN_WINDOW过程； </li>
                                    </ul>
                                    <p>　　注意WINDOW是依赖于其调度的，因此在手动打开WINDOW时，必须为其指定duration属性： </p>
                                    <div class="articleBlockGrey">
                                    <ul>
                                        <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.open_window(&#168;sys.my_first_wd1&#168;,interval&nbsp;&#168;1&#168;&nbsp;hour);; </p>
                                        PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                        </div>
                                        <ul>
                                            <li>手动关闭WINDOW，使用CLOSE_WINDOW过程； </li>
                                        </ul>
                                        <div class="articleBlockGrey">
                                        <ul>
                                            <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.close_window(&#168;sys.my_first_wd1&#168;); </p>
                                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                            </div>
                                            <p>　　关闭和打开WINDOW，都会记录日志，大家可以通过*_SCHEDULER_WINDOW_LOG视图中获取这部分信息。 </p>
                                            <h4>３、关于WINDOW&nbsp;GROUP </h4>
                                            <p>　　除了WINDOW外，还有一个与WINDOW有关系的叫WINDOW&nbsp;GROUP，一个WINDOW&nbsp;GROUP可能包 含多个WINDOW。使用WINDOW&nbsp;GROUP的本意是这样的，假如说某个job执行的时间比较长，甚至全天24小时都在执行，对于这类job，单个WINDOW很难有效调整其资源占用，这时间呢，就可以通过设置一个WINDOW&nbsp;GROUP，该WINDOW&nbsp;GROUP中包含了多个WINDOW，每个WINDOW分别负责不同时间点时的资源使用计划。 </p>
                                            <p>　　然后在创建JOB时，指定schedule_name参数为WINDOW&nbsp;GROUP的名称(想不到SCHEDULE_NAME还能指定为WINDOW&nbsp;GROUP哪，其实何止WINDOW&nbsp;GROUP，还可以直接指定成WINDOW哪)，这样，就可以通过很简单的方式，将job与window联系在一起了。 </p>
                                            <p>　　WINDOW&nbsp;GROUP 的创建和管理与前面介绍的方式极其相似： </p>
                                            <ul>
                                                <li>创建，使用CREATE_WINDOW_GROUP过程；
                                                <li>删除，使用DROP_WINDOW_GROUP过程；
                                                <li>添加WINDOW成员，使用ADD_WINDOW_GROUP_MEMBER过程；
                                                <li>删除WINDOW成员，使用REMOVE_WINDOW_GROUP_MEMBER过程；
                                                <li>启用，使用ENABLE过程；
                                                <li>禁用，使用DISABLE过程； </li>
                                            </ul>
                                            <p>　　这些过程的调用方式也都非常简单，这里就不着重演示了，感兴趣的朋友不妨自行尝试。 </p>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303635.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:24 <a href="http://www.blogjava.net/javaex/articles/303635.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (11)使用Job Classes 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-using-job-classes.shtml</title><link>http://www.blogjava.net/javaex/articles/303634.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:23:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303634.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303634.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303634.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303634.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(11)使用Job Classes</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-9-8</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h2>六、使用Job&nbsp;Classes </h2>
            <p>　　Job&nbsp;Classes 相当于创建了一个job组，DBA可以将那些具有相同特性的job，统统放到相同的Job&nbsp;Classes中，然后通过对Job&nbsp;Class应用ORACLE中的"资源使用计划"特性，就可以对这些job执行过程中所需要的资源分配情况进行管理。 </p>
            <h4>1、 创建Job&nbsp;Classes </h4>
            <p>　　使用DBMS_SCHEDULER包的CREATE_JOB_CLASS过程创建Job&nbsp;Classes，该过程支持的参数如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>JSSWEB&gt; &nbsp;desc&nbsp;dbms_scheduler.create_job_class; </p>
                <p>Parameter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                <p>-----------------------&nbsp;--------------&nbsp;----&nbsp;--------&nbsp; </p>
                <p>JOB_CLASS_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>RESOURCE_CONSUMER_GROUP&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>SERVICE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>LOGGING_LEVEL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BINARY_INTEGER&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>LOG_HISTORY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BINARY_INTEGER&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                COMMENTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </ul>
                </div>
                <p>　　其中： </p>
                <ul>
                    <li>JOB_CLASS_NAME ：要创建的Job&nbsp;Class的名称，注意指定的长度不要超过30个字符，也不要与现有Job&nbsp;Class同名；
                    <li>RESOURCE_CONSUMER_GROUP ：指定创建的Job&nbsp;Class所在的RCG； </li>
                </ul>
                <div class="articleBlockGrey">
                <ul>
                    <p>提示：啥是Resource&nbsp;Consumer&nbsp;Group </p>
                    你可以将其理解成一个资源分配的方式，处于相同RCG组中的用户、会话、或者对象共用一组资源，这组资源中可供分配的资源按照DBA指定的方式分配给RCG。如果设计合理，通过这种方式，可以更有效的利用服务器的资源。 </ul>
                    </div>
                    <ul>
                        <li>SERVICE ：指定创建的Job&nbsp;Class所在Service，本选项常见于RAC环境，我们都知道RAC环境由多实例+数据库组成，此处所指定的Service实际就是指Job&nbsp;Class会在哪个实例上运行。</li>
                    </ul>
                    <div class="articleBlockGrey">
                    <ul>注意：本参数与RESOURCE_CONSUMER_GROUP参数相互冲突，同一个Job&nbsp;Class只同设置两个参数中的一个值。 </ul>
                        </div>
                        <ul>
                            <li>LOGGING_LEVEL ：指定日志记录的级别，有下列三种级别：
                            <ul>
                                <li>n&nbsp; DBMS_SCHEDULER.LOGGING_OFF ：关闭日志记录功能；
                                <li>n&nbsp; DBMS_SCHEDULER.LOGGING_RUNS ：对该Job&nbsp;Class下所有任务的运行信息进行记录；
                                <li>n&nbsp; DBMS_SCHEDULER.LOGGING_FULL ：记录该Job&nbsp;Class下任务的所有相关信息，不仅有任务的运行情况，甚至连任务的创建、修改等也均将记入日志。 </li>
                            </ul>
                            <li>LOG_HISTORY ：指定日志记录的时间，以天为单位，比如指定LOG_HISTORY参数值为90，就表示日志信息保留最近90天的内容。
                            <li>COMMENTS ：指定注释信息。 </li>
                        </ul>
                        <p>　　上述各个参数，除了LOG_CLASS_NAME参数为必选参外，其它均为可选参数，例如： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>JSSWEB&gt; &nbsp;EXEC&nbsp;DBMS_SCHEDULER.CREATE_JOB_CLASS(&#168;my_first_jc&#168;); </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed </ul>
                            </div>
                            <p>　　查询系统中已经存在的Job&nbsp;Classes，可以通过DBA_SCHEDULER_JOB_CLASSES视图(或ALL_SCHEDULER_JOB_CLASS视图)，例如： </p>
                            <div class="articleBlockGrey">
                            <ul>
                                <p>JSSWEB&gt;&nbsp;select&nbsp;job_class_name,resource_consumer_group,service&nbsp;from&nbsp;dba_scheduler_job_classes; </p>
                                <p>JOB_CLASS_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RESOURCE_CONSUMER_GROUP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SERVICE </p>
                                <p>------------------------------&nbsp;------------------------------&nbsp;----------------------------- </p>
                                <p>DEFAULT_JOB_CLASS </p>
                                <p>AUTO_TASKS_JOB_CLASS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AUTO_TASK_CONSUMER_GROUP </p>
                                MY_FIRST_JC </ul>
                                </div>
                                <p>　　当创建Jobs时，可以通过JOB_CLASS参数来指定job所在的Job&nbsp;Class，如果不指定的话，创建的job默认属于DEFAULT_JOB_CLASS。至于说如何查询创建的jobs属于哪个Job&nbsp;Class，还用说吗，*_SCHEDULER_JOBS视图中的JOB_CLASS列呗。 </p>
                                <h4>2、 管理Job&nbsp;Classes </h4>
                                <p>　　DBMS_SCHEDULER.SET_ATTRIBUTE 过程大家应当还记的，前面的小节中演示中使用该过程，修改job的属性，实际上SET_ATTRIBUTE也同样可以用来修改Job&nbsp;Class的属性，操作方法与修改job属性完全相同，只不过作用函概的范围更广，修改Job&nbsp;Class后，该Job&nbsp;Class下属的所有job属性都会被级联修改(当前正运行的不会立刻生效，将等到下次运行时生效)。 </p>
                                <p>　　例如：修改刚刚创建的MY_FIRST_JC的日志保存时间： </p>
                                <div class="articleBlockGrey">
                                <ul>
                                    <p>JSSWEB&gt;&nbsp;EXEC&nbsp;DBMS_SCHEDULER.SET_ATTRIBUTE(&#168;SYS.MY_FIRST_JC&#168;,&#168;LOG_HISTORY&#168;,&#168;30&#168;); </p>
                                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                    </div>
                                    <div class="articleBlockGrey">
                                    <ul>提示：Job&nbsp;Class可被修改的属性，即创建时可选择指定的那5个属性。 </ul>
                                        </div>
                                        <h4>3、 删除Job&nbsp;Classes </h4>
                                        <p>　　DBMS_SCHEDULER 包提供了DROP_JOB_CLASS过程，用来删除Job&nbsp;Classes。该过程调用非常简单，例如，删除刚刚创建的MY_FIRST_JC，执行命令如下： </p>
                                        <div class="articleBlockGrey">
                                        <ul>
                                            <p>JSSWEB&gt;&nbsp;EXEC&nbsp;DBMS_SCHEDULER.DROP_JOB_CLASS(&#168;MY_FIRST_JC&#168;); </p>
                                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                            </div>
                                            <p>　　如果有多个Job&nbsp;Classes需要删除，并不需要多次执行DROP_JOB_CLASS，只需要在为该过程指定值时，参数值间以逗号分隔即可。 </p>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:23 <a href="http://www.blogjava.net/javaex/articles/303634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (10)使用Chains之管理CHAIN 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-alter-chains.shtml</title><link>http://www.blogjava.net/javaex/articles/303632.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:18:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303632.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303632.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303632.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303632.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303632.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(10)使用Chains之管理CHAIN</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-9-7</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h3>5.2&nbsp; 管理Chains </h3>
            <h4>5.2.1&nbsp; 修改Chains属性 </h4>
            <p>　　基本上碰到修改CHAIN属性的机率不会太大，因此确实没啥可修改的，对于CHAIN对象来说，能够修改的属性只有两个：evaluation_interval和comments，这两个参数一般情况下甚至都不会进行设置。如果你碰到了确实需要修改的情况，没问题，DBMS_SCHEDULER.SET_ATTRIBUTE过程还记的吧，没错，修改CHAIN也是用它。例如： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>SQL&gt;&nbsp;select&nbsp;chain_name,comments&nbsp;from&nbsp;user_scheduler_chains; </p>
                <p>CHAIN_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMMENTS </p>
                <p>--------------------&nbsp;-------------------------- </p>
                <p>MY_CHAIN1 </p>
                <p>SQL&gt;&nbsp; exec&nbsp;dbms_scheduler.set_attribute(&#168;my_chain1&#168;,&#168;comments&#168;,&#168;change&nbsp;it&nbsp;for&nbsp;a&nbsp;test!&#168;); </p>
                <p>PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </p>
                <p>SQL&gt;&nbsp;select&nbsp;chain_name,comments&nbsp;from&nbsp;user_scheduler_chains; </p>
                <p>CHAIN_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMMENTS </p>
                <p>--------------------&nbsp;-------------------------- </p>
                MY_CHAIN1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change&nbsp;it&nbsp;for&nbsp;a&nbsp;test&nbsp;! </ul>
                </div>
                <h4>5.2.2&nbsp; 设置Chain&nbsp;Step运行属性 </h4>
                <p>　　修改Chain&nbsp;Step的运行属性就不能使用DBMS_SCHEDULER.SET_ATTRIBUTE了，而是有专门的过程DBMS_SCHEDULER.ALTER_CHAIN处理，该过程的定义如下： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;desc&nbsp;dbms_scheduler.alter_chain; </p>
                    <p>Parameter&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                    <p>----------&nbsp;--------&nbsp;----&nbsp;--------&nbsp; </p>
                    <p>CHAIN_NAME&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                    <p>STEP_NAME&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                    <p>ATTRIBUTE&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                    VALUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOLEAN&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </ul>
                    </div>
                    <p>　　前两个参数就不说了，ATTRIBUTE参数用来指定STEP的属性值，可设定的属性值有3个，每个属性值都有TRUE和FALSE两个选项，由VALUE参数指定： </p>
                    <ul>
                        <li>PAUSE ：设置该参数值为TRUE时，当step运行时，其运行状态就会变更为PAUSED；
                        <li>SKIP ：设置该参数值为TRUE时，当step满足运行条件时，并不是执行step中的program，而是直接跳过，注意当SKIP参数值设置为TRUE，并且PAUSE参数值也被设置为TRUE，那么将会以PAUSE的状态优先；
                        <li>RESTART_ON_RECOVERY ：设置该参数值为TRUE时，如果由于数据库shutdown导致step被停止，那么当下次数据库启动时，step会自动重新运行。 </li>
                    </ul>
                    <p>　　DBMS_SCHEDULER.ALTER_CHAIN 过程修改Chain&nbsp;Step属性后，只有当下次运行时才会生效，如果要修改当前运行中Chain&nbsp;Step的属性，也有一个专门的过程DBMS_SCHEDULER.ALTER_RUNNING_CHAIN进行处理，该过程语法与DBMS_SCHEDULER.ALTER_CHAIN一模一样，这里就不详细介绍了。 </p>
                    <h4>5.2.3&nbsp; 删除Chain&nbsp;Rules </h4>
                    <p>　　Chain&nbsp;Rules 没有对应的修改方法，如果要修改某个Chain的rule，只能首先删除不适当的rule，然后重新添加新rule(所谓添加，其实就是再重新定义一个rule)。 </p>
                    <p>　　删除Chain&nbsp;Rule有专门的过程DBMS_SCHEDULER.DROP_CHAIN_RULE，该过程语法如下： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;desc&nbsp;dbms_scheduler.drop_chain_rule; </p>
                        <p>Parameter&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                        <p>----------&nbsp;--------&nbsp;----&nbsp;--------&nbsp; </p>
                        <p>CHAIN_NAME&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                        <p>RULE_NAME&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                        FORCE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOLEAN&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </ul>
                        </div>
                        <p>　　<a title="点击阅读三思笔记---诙谐幽默简单易读的ORACLE学习文章" href="http://www.5ienet.com/note" target="_blank">三思</a>一眼就能看出来，这个过程的调用方式那是相当简单，因此就不对各个参数详细介绍了，下面举个简单的示例，比如删除前面定义的my_rule3，执行过程如下： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.drop_chain_rule(&#168;my_chain1&#168;,&#168;my_rule3&#168;,true); </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                            </div>
                            <h4>5.2.4&nbsp; 删除Chain&nbsp;Steps </h4>
                            <p>　　删除Chain&nbsp;Step也有专门的过程DBMS_SCHEDULER.DROP_CHAIN_STEP进行处理，该过程语法如下： </p>
                            <div class="articleBlockGrey">
                            <ul>
                                <p>SQL&gt;&nbsp;desc&nbsp;dbms_scheduler.drop_chain_step; </p>
                                <p>Parameter&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                                <p>----------&nbsp;--------&nbsp;----&nbsp;--------&nbsp; </p>
                                <p>CHAIN_NAME&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                                <p>STEP_NAME&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                                FORCE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOLEAN&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp; </ul>
                                </div>
                                <p>　　看着有点儿眼熟是吧，没错，与drop_chain_rule的相似度高达90%以上。例如，删除之前定义的my_step3，执行过程如下： </p>
                                <div class="articleBlockGrey">
                                <ul>
                                    <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.drop_chain_step(&#168;my_chain1&#168;,&#168;my_step3&#168;,true); </p>
                                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                    </div>
                                    <h4>5.2.5&nbsp; 删除Chains </h4>
                                    <p>　　如果要删除Chain那就更简单了，执行dbms_scheduler.drop_chain过程即可，例如： </p>
                                    <div class="articleBlockGrey">
                                    <ul>
                                        <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.drop_chain(&#168;my_chain1&#168;,true); </p>
                                        PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                        </div>
                                        <p>　　注意，执行drop_chain时，如果不指定force参数为TRUE，那么默认情况下ORACLE会首先检查要删除的CHAIN是否还有被依赖的对象，如果存在的话，会报ORA-27479错误，提示仍然有依赖的对象(所谓依赖的对象就是指，该chain仍然存在chain_step或chain_rule之类)，因此无法直接删除。这种情况下解决方案有两种：一是手动删除所有相关的chain_step和chain_rule，然后再执行chain的删除，再就是附加force参数并指定参数值为true，这样ORACLE就会自动替你清除所有依赖的对象了。 </p>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303632.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:18 <a href="http://www.blogjava.net/javaex/articles/303632.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (9)使用Chains之创建CHAIN 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-create-chains.shtml</title><link>http://www.blogjava.net/javaex/articles/303631.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:17:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303631.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303631.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303631.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303631.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303631.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(9)使用Chains之创建CHAIN</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-9-4</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h2>五、使用Chains </h2>
            <p>　　今天要来认识一位新同学：CHAIN(注意不要敲成CHINA)。CHAIN可以被视做一组Programs的复合，举个简单的例子：运行PROGRAM:A以及PROGRAM:B，如果成功的话继续运行PROGRAM:C，否则的话运行PROGRAM:D。Programs:A、B、C、D以及执行的逻辑关系就构成了一个最简单的CHAIN。 </p>
            <p>　　关于CHAIN的管理操作比较多，比如创建/删除/修改Chains，添加/修改/删除Chain&nbsp;Steps等等。 </p>
            <h3>5.1&nbsp; 创建Chains </h3>
            <h4>5.1.1&nbsp; 创建CHAIN对象 </h4>
            <p>　　创建CHAIN使用DBMS_SCHEDULER.CREATE_CHAIN过程，这个过程调用非常简单，因为需要指定的参数极少，该过程的定义如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>SQL&gt;&nbsp;desc&nbsp;dbms_scheduler.create_chain; </p>
                <p>Parameter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                <p>-------------------&nbsp;----------------------&nbsp;----&nbsp;--------&nbsp; </p>
                <p>CHAIN_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>RULE_SET_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>EVALUATION_INTERVAL&nbsp;INTERVAL&nbsp;DAY&nbsp;TO&nbsp;SECOND&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                COMMENTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </ul>
                </div>
                <p>　　在创建时，甚至可以简单到只指定一个CHAIN的名称，其它均为空即可，例如： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.create_chain(&#168;my_chain1&#168;); </p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <p>　　定义好的Chains，可以通过*_SCHEDULER_CHAINS视图查看，例如： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;select&nbsp;chain_name&nbsp;from&nbsp;user_scheduler_chains; </p>
                        <p>CHAIN_NAME </p>
                        <p>------------------------------ </p>
                        MY_CHAIN1 </ul>
                        </div>
                        <p>　　注意，不是说创建了CHAIN就齐活，只有一个CHAIN对象ORACLE还是啥也干不了(当然啦，相信从上面执行的创建语句大家也看出来了)，CHAIN对象创建之后，要做的工作其实才刚刚开始。其后，还需要定义Chain&nbsp;Steps以及Chain&nbsp;rules。 </p>
                        <h4>5.1.2&nbsp; 创建Chain&nbsp;Step </h4>
                        <p>　　Chain&nbsp;Steps 就是用来指定CHAIN执行的操作及执行步骤，创建CHAIN&nbsp;STEP是通过DBMS_SCHEDULER.DEFINE_CHAIN_STEP过程进行，例如，为刚刚创建的my_chain1添加一个step，执行操作如下： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;begin </p>
                            <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.DEFINE_CHAIN_STEP&nbsp;( </p>
                            <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_chain1&#168;, </p>
                            <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;step_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_step1&#168;, </p>
                            <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_name&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;p_p1&#168;); </p>
                            <p>&nbsp;&nbsp;6&nbsp;&nbsp;end; </p>
                            <p>&nbsp;&nbsp;7&nbsp;&nbsp;/ </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                            </div>
                            <p>　　Chain&nbsp;Steps 即可以调用PROGRAM(注意是program，不是procedure，当然program中可以定义执行procedure)，也可以调用EVENT，甚至调用其它CHAIN(这就叫嵌套CHAIN)。 </p>
                            <p>　　下面接着为my_chain1添加两个step，操作如下： </p>
                            <div class="articleBlockGrey">
                            <ul>
                                <p>SQL&gt;&nbsp;begin </p>
                                <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.DEFINE_CHAIN_STEP&nbsp;( </p>
                                <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_chain1&#168;, </p>
                                <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;step_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_step2&#168;, </p>
                                <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_name&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;p_p2&#168;); </p>
                                <p>&nbsp;&nbsp;6&nbsp;&nbsp;DBMS_SCHEDULER.DEFINE_CHAIN_STEP&nbsp;( </p>
                                <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_chain1&#168;, </p>
                                <p>&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;step_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_step3&#168;, </p>
                                <p>&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_name&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;p_p3&#168;); </p>
                                <p>&nbsp;10&nbsp;&nbsp;end; </p>
                                <p>&nbsp;11&nbsp;&nbsp;/ </p>
                                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                </div>
                                <p>　　要查询定义的Chain&nbsp;Steps，则是通过*_SCHEDULER_CHAIN_STEPS视图，例如： </p>
                                <div class="articleBlockGrey">
                                <ul>
                                    <p>SQL&gt;&nbsp;select&nbsp;chain_name,step_name,program_name&nbsp;from&nbsp;user_scheduler_chain_steps; </p>
                                    <p>CHAIN_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STEP_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROGRAM_NAME </p>
                                    <p>--------------------&nbsp;--------------------&nbsp;-------------------- </p>
                                    <p>MY_CHAIN1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MY_STEP1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P_P1 </p>
                                    <p>MY_CHAIN1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MY_STEP2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P_P2 </p>
                                    MY_CHAIN1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MY_STEP3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P_P3 </ul>
                                    </div>
                                    <h4>5.1.3&nbsp; 创建Chain&nbsp;Rule </h4>
                                    <p>　　接下来，要为CHAIN的运行定义规则。定义规则是使用DBMS_SCHEDULER.DEFINE_CHAIN_RULE过程，Chain&nbsp;Rules依赖于Chain&nbsp;Steps，每个CHAIN&nbsp;RULE都拥有condition和action属性，当满足condition时则执行action中指定的step。 </p>
                                    <p>　　DBMS_SCHEDULER.DEFINE_CHAIN_RULE 过程的语法如下： </p>
                                    <div class="articleBlockGrey">
                                    <ul>
                                        <p>SQL&gt;&nbsp;desc&nbsp;dbms_scheduler.define_chain_rule; </p>
                                        <p>Parameter&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                                        <p>----------&nbsp;--------&nbsp;----&nbsp;--------&nbsp; </p>
                                        <p>CHAIN_NAME&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                                        <p>CONDITION&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                                        <p>ACTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                                        <p>RULE_NAME&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                                        COMMENTS&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </ul>
                                        </div>
                                        <p>　　CHAIN_NAME 就不说了，需要注意的是CONDITION和ACTION两个参数。在为condition参数指定值时，其语法看起来稍稍复杂一些，或者说是灵活，condition参数值支持下列的语法形式： </p>
                                        <ul>
                                            <li>TRUE
                                            <li>FALSE
                                            <li>stepname&nbsp;[NOT]&nbsp;SUCCEEDED&nbsp;
                                            <li>stepname&nbsp;[NOT]&nbsp;FAILED&nbsp;
                                            <li>stepname&nbsp;[NOT]&nbsp;STOPPED&nbsp;
                                            <li>stepname&nbsp;[NOT]&nbsp;COMPLETED&nbsp;
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;IN&nbsp;(integer,&nbsp;integer,&nbsp;integer&nbsp;...)
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;NOT&nbsp;IN&nbsp;(integer,&nbsp;integer,&nbsp;integer&nbsp;...)
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;=&nbsp;integer
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;!=&nbsp;integer
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;&lt;&gt;&nbsp;integer
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;&gt;&nbsp;integer
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;&gt;=&nbsp;integer
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;&lt;&nbsp;integer
                                            <li>stepname&nbsp;ERROR_CODE&nbsp;&lt;=&nbsp;integer </li>
                                        </ul>
                                        <p>　　甚至于，还可以制定成下列逻辑语法： </p>
                                        <ul>
                                            <li>expression&nbsp;AND&nbsp;expression
                                            <li>expression&nbsp;OR&nbsp;expression
                                            <li>NOT&nbsp;(expression) </li>
                                        </ul>
                                        <p>　　比如说，我们希望条件为step1成功运行，那么可以指定condition参数值如下： </p>
                                        <div class="articleBlockGrey">
                                        <ul>&#168;step1&nbsp;completed&#168; </ul>
                                            </div>
                                            <p>　　Action 参数相对简单一些，这个参数用来指定当满足condition参数时，CHAIN执行的操作。 </p>
                                            <p>　　例如，创建CHAIN&nbsp;RULE，首先执行my_step1，如果my_step1成功执行的话，就继续执行my_step2，如果my_step2也成功执行的话，则结束该CHAIN，创建脚本如下： </p>
                                            <div class="articleBlockGrey">
                                            <ul>
                                                <p>SQL&gt;&nbsp;BEGIN </p>
                                                <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.DEFINE_CHAIN_RULE&nbsp;( </p>
                                                <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain_name&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_chain1&#168;, </p>
                                                <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;condition&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;TRUE&#168;, </p>
                                                <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;START&nbsp;my_step1&#168;, </p>
                                                <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule_name&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_rule1&#168;); </p>
                                                <p>&nbsp;&nbsp;7&nbsp;&nbsp;DBMS_SCHEDULER.DEFINE_CHAIN_RULE&nbsp;( </p>
                                                <p>&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain_name&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_chain1&#168;, </p>
                                                <p>&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;condition&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_step1&nbsp;completed&#168;, </p>
                                                <p>&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;START&nbsp;my_step2&#168;, </p>
                                                <p>&nbsp;11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule_name&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_rule2&#168;); </p>
                                                <p>&nbsp;12&nbsp;&nbsp;DBMS_SCHEDULER.DEFINE_CHAIN_RULE&nbsp;( </p>
                                                <p>&nbsp;13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain_name&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_chain1&#168;, </p>
                                                <p>&nbsp;14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;condition&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_step2&nbsp;completed&#168;, </p>
                                                <p>&nbsp;15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;end&nbsp;0&#168;, </p>
                                                <p>&nbsp;16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule_name&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&nbsp;&#168;my_rule3&#168;); </p>
                                                <p>&nbsp;17&nbsp;&nbsp;END; </p>
                                                <p>&nbsp;18&nbsp;&nbsp;/ </p>
                                                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                                </div>
                                                <h4>5.1.4&nbsp; 运行Chains </h4>
                                                <p>　　最后，来运行一下创建的my_chain1吧，手动运行CHAIN是通过DBMS_SCHEDULER.RUN_CHAIN过程，例如： </p>
                                                <div class="articleBlockGrey">
                                                <ul>
                                                    <p>SQL&gt;&nbsp;BEGIN </p>
                                                    <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.RUN_CHAIN&nbsp;( </p>
                                                    <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain_name&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_chain1&#168;, </p>
                                                    <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_steps&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_step1&#168;); </p>
                                                    <p>&nbsp;&nbsp;5&nbsp;&nbsp;END; </p>
                                                    <p>&nbsp;&nbsp;6&nbsp;&nbsp;/ </p>
                                                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                                    </div>
                                                    <p>　　语句执行成功，下面需要查看一下执行的结果。我们之前定义的p_p1等program对象，实际上是调用procedure，向一个指定表jss_t2中插入记录，这里直接查询一下该表，就知道执行情况了(在此之前，jss_t2表为空)： </p>
                                                    <div class="articleBlockGrey">
                                                    <ul>
                                                        <p>SQL&gt;&nbsp;select&nbsp;*&nbsp;from&nbsp;jss_t2; </p>
                                                        <p>TP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DT </p>
                                                        <p>------------------------------&nbsp;------------ </p>
                                                        <p>p_p1&nbsp;inserted&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;03-SEP-09 </p>
                                                        p_p2&nbsp;inserted&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;03-SEP-09 </ul>
                                                        </div>
                                                        <p>　　你看，jss_t2表中有了两条记录，对应前面设置的CHAIN&nbsp;RULE，说明my_step1和my_step2均已正确执行。 </p>
                                                        <div class="articleBlockGrey">
                                                        <ul>提示：Chains在执行前，必须被置于enabled状态，默认情况下刚刚创建的CHAIN都是disabled状态，要修改Chains的状态，还是通过DBMS_SCHEDULER.ENABLE和DBMS_SCHEDULER.DISABLE两过程，这里就不演示了。 </ul>
                                                            </div>
                                                            <p>　　手动执行的CHAIN的话没有系统级的日志记录，因此如果希望看到详细执行情况的话，建议创建job来执行CHAIN，例如： </p>
                                                            <div class="articleBlockGrey">
                                                            <ul>
                                                                <p>SQL&gt;&nbsp;BEGIN </p>
                                                                <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.CREATE_JOB&nbsp;( </p>
                                                                <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;chain_job_1&#168;, </p>
                                                                <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;CHAIN&#168;, </p>
                                                                <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;my_chain1&#168;, </p>
                                                                <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repeat_interval&nbsp;=&gt;&nbsp;&#168;freq=daily;interval=1&#168;, </p>
                                                                <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enabled&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;TRUE); </p>
                                                                <p>&nbsp;&nbsp;8&nbsp;&nbsp;END; </p>
                                                                <p>&nbsp;&nbsp;9&nbsp;&nbsp;/ </p>
                                                                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                                                </div>
                                                                <p>　　然后，dba就可以通过定期观察*_scheduler_job_run_details视图来确认chain的执行情况了。 </p>
                                                                </td>
                                                            </tr>
                                                        </tbody>
                                                    </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303631.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:17 <a href="http://www.blogjava.net/javaex/articles/303631.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (8)使用Events之Aapplication抛出的Events 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-using-application-events.shtml</title><link>http://www.blogjava.net/javaex/articles/303630.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303630.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303630.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303630.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303630.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303630.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(8)使用Events之Aapplication抛出的Events</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-8-26</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h3>4.2&nbsp;Application抛出的Events </h3>
            <p>　　首先要说明，这里所说的Application是个代词，即可以表示ORACLE数据库之外的应用程序，也可以是ORACLE数据库中的PROCEDURE等对象，总之你就将其理解成用户自己创建的对象就好了。 </p>
            <p>　　Scheduler 能够抛出Events让外部应用处理，外部的应用也可以抛出Events让Scheduler启动job处理，不过并不是任何job都能够对外部应用抛出的Events做出响应，必须在创建jobs时明确指定响应的事件。那么如何指定呢？依靠下列两个附加的参数： </p>
            <ul>
                <li>queue_spec ：指定外部应用抛出的events消息入队的队列名；
                <li>event_condition ：指定触发job启动的条件，这一参数的参数值在设置时应当基于事件消息的自身属性，因为事件消息在入队时，消息的属性都是由application定义的，因此在设置触发条件时，也应该根据这些属性值就行设置。 </li>
            </ul>
            <p>　　下面，我们就演示创建一个由event触发启动的job，在此之前，首先需要进行一些准备工具，比如创建队列，由于队列需要基于一个队列表，因此在创建队列之前，首先要创建一个队列表，考虑到队列表需要依赖一个对象类型，因此在创建队列表之前，先得创建一个type.......复杂，具体的操作步骤如下，客官可要看仔细了： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>SQL&gt;&nbsp;create&nbsp;or&nbsp;replace&nbsp;type&nbsp;jss_type 1 &nbsp;as&nbsp;object </p>
                <p>&nbsp;&nbsp;2&nbsp;&nbsp;( </p>
                <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;event_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2( 1 0), </p>
                <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;object_owner&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2( 30 ), </p>
                <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;object_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2( 3 0) </p>
                <p>&nbsp;&nbsp;6&nbsp;&nbsp;); </p>
                <p>&nbsp;&nbsp;7&nbsp;&nbsp;/ </p>
                <p>Type&nbsp;created. </p>
                <p>SQL&gt;&nbsp;begin </p>
                <p>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;dbms_aqadm.create_queue_table( </p>
                <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue_table&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;my_queue_tbl1&#168;, </p>
                <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue_payload_type&nbsp;=&gt;&nbsp;&#168;JSS_TYPE1&#168;, </p>
                <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;multiple_consumers&nbsp;=&gt;&nbsp;true); </p>
                <p>&nbsp;&nbsp;6&nbsp;&nbsp;end; </p>
                <p>&nbsp;&nbsp;7&nbsp;&nbsp;/ </p>
                <p>PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </p>
                <p>SQL&gt;&nbsp;begin </p>
                <p>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;dbms_aqadm.create_queue( </p>
                <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue_name&nbsp;&nbsp;=&gt;&nbsp;&#168;event_t1&#168;, </p>
                <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue_table&nbsp;=&gt;&nbsp;&#168;my_queue_tbl1&#168;); </p>
                <p>&nbsp;&nbsp;5&nbsp;&nbsp;end; </p>
                <p>&nbsp;&nbsp;6&nbsp;&nbsp;/ </p>
                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                </div>
                <p>　　OK, 准备工作完成，下面就来创建一个event触发启动的job，创建脚本如下： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;BEGIN </p>
                    <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.CREATE_JOB&nbsp;( </p>
                    <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;EVENT_JOB_T1&#168;, </p>
                    <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;STORED_PROCEDURE&#168;, </p>
                    <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;P_INSERTINTOTEST&#168;, </p>
                    <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event_condition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;tab.user_data.event_type&nbsp;=&nbsp;&#168;&#168;OP_INSERT&#168;&#168;&#168;, </p>
                    <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue_spec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;EVENT_T1&#168;, </p>
                    <p>&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enabled&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;TRUE); </p>
                    <p>&nbsp;&nbsp;9&nbsp;&nbsp;END; </p>
                    <p>&nbsp;10&nbsp;&nbsp;/ </p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <p>　　上述脚本仅做演示，因此创建的job仍然执行P_INSERTINTOTEST过程。 </p>
                    <p>　　<a title="点击阅读三思笔记---诙谐幽默简单易读的ORACLE学习文章" href="http://www.5ienet.com/note" target="_blank">三思</a>并不准备再编写一套外部的应用来触发，这里仅为了演示application触发job启动的示例，因此<a title="点击阅读三思笔记---诙谐幽默简单易读的ORACLE学习文章" href="http://www.5ienet.com/note" target="_blank">三思</a>决定通过pl/sql直接向event_t1队列中添加消息的方式，触发job的启动，具体操作如下。 </p>
                    <p>　　首先要执行DBMS_AQADM.START_QUEUE过程，将event_t1置于允许入队和出队状态(默认情况下创建的队列是不允许出队和入队操作的)，脚本如下： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;exec&nbsp;dbms_aqadm.start_queue(queue_name&nbsp;=&gt;&nbsp;&#168;event_t1&#168;,enqueue&nbsp;=&gt;&nbsp;true,dequeue&nbsp;=&gt;&nbsp;true); </p>
                        PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                        </div>
                        <p>　　执行入队操作： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;declare </p>
                            <p>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;v_Message&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jss_type1; </p>
                            <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;v_EnqueueOptions&nbsp;&nbsp;&nbsp;&nbsp;dbms_aq.enqueue_options_t; </p>
                            <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;v_MessageProperties&nbsp;dbms_aq.message_properties_t; </p>
                            <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;v_msg_handle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raw(16); </p>
                            <p>&nbsp;&nbsp;6&nbsp;&nbsp;begin </p>
                            <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;v_message&nbsp;:=&nbsp;jss_type1(&#168;OP_ SELECT &#168;,&nbsp;user,&nbsp;&#168;tmpObj&#168;); </p>
                            <p>&nbsp;&nbsp;8 </p>
                            <p>&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;dbms_aq.enqueue(queue_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;event_t1&#168;, </p>
                            <p>&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enqueue_options&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;v_enqueueOptions, </p>
                            <p>&nbsp;11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message_properties&nbsp;=&gt;&nbsp;v_messageproperties, </p>
                            <p>&nbsp;12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;payload&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;v_message, </p>
                            <p>&nbsp;13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msgid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;v_msg_handle); </p>
                            <p>&nbsp;14&nbsp;&nbsp;&nbsp;&nbsp;commit; </p>
                            <p>&nbsp;15 </p>
                            <p>&nbsp;16&nbsp;&nbsp;end; </p>
                            <p>&nbsp;17&nbsp;&nbsp;/ </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                            </div>
                            <p>　　查询队列表中的数据： </p>
                            <div class="articleBlockGrey">
                            <ul>
                                <p>SQL&gt;&nbsp;select&nbsp;user_data&nbsp;from&nbsp;my_queue_tbl1; </p>
                                <p>USER_DATA(EVENT_TYPE,&nbsp;OBJECT_OWNER,&nbsp;OBJECT_NAME) </p>
                                <p>--------------------------------------------------------- </p>
                                JSS_TYPE1(&#168;OP_SELECT&#168;,&nbsp;&#168;TEST&#168;,&nbsp;&#168;tmpObj&#168;) </ul>
                                </div>
                                <p>　　然后查询job </p>
                                <div class="articleBlockGrey">
                                <ul>
                                    <p>SQL&gt;&nbsp;select&nbsp;to_char(created,&#168;yyyy-mm-dd&nbsp;hh24:mi:ss&#168;)&nbsp;from&nbsp;jss_1; </p>
                                    <p>TO_CHAR(CREATED,&#168;YY </p>
                                    <p>------------------- </p>
                                    2009-08-25&nbsp;12:49:29 </ul>
                                    </div>
                                    <p>　　看起来jss_1表中并未有新增加记录，似乎job没有执行啊。这很正常，还记得咱们创建job时指定的 event_condition 条件吗： </p>
                                    <div class="articleBlockGrey">
                                    <ul>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event_condition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;tab.user_data.event_type&nbsp;=&nbsp;&#168;&#168;OP_INSERT&#168;&#168;&#168;, </ul>
                                        </div>
                                        <p>　　没错，只有当event_type为&#168;OP_INSERT&#168;时才会触发job的执行，前面入队时指定的是 OP_ SELECT ，当然没有触发job中指定的procedure啦，下面再次执行入队操作： </p>
                                        <div class="articleBlockGrey">
                                        <ul>
                                            <p>SQL&gt;&nbsp;declare </p>
                                            <p>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;v_Message&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jss_type1; </p>
                                            <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;v_EnqueueOptions&nbsp;&nbsp;&nbsp;&nbsp;dbms_aq.enqueue_options_t; </p>
                                            <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;v_MessageProperties&nbsp;dbms_aq.message_properties_t; </p>
                                            <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;v_msg_handle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raw(16); </p>
                                            <p>&nbsp;&nbsp;6&nbsp;&nbsp;begin </p>
                                            <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;v_message&nbsp;:=&nbsp;jss_type1(&#168;OP_INSERT&#168;,&nbsp;user,&nbsp;&#168;tmpObj&#168;); </p>
                                            <p>&nbsp;&nbsp;8 </p>
                                            <p>&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;dbms_aq.enqueue(queue_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;event_t1&#168;, </p>
                                            <p>&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enqueue_options&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;v_enqueueOptions, </p>
                                            <p>&nbsp;11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message_properties&nbsp;=&gt;&nbsp;v_messageproperties, </p>
                                            <p>&nbsp;12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;payload&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;v_message, </p>
                                            <p>&nbsp;13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msgid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;v_msg_handle); </p>
                                            <p>&nbsp;14&nbsp;&nbsp;&nbsp;&nbsp;commit; </p>
                                            <p>&nbsp;15 </p>
                                            <p>&nbsp;16&nbsp;&nbsp;end; </p>
                                            &nbsp;&nbsp;17&nbsp;&nbsp;/ </ul>
                                            </div>
                                            <p>　　再次查看jss_1表看看： </p>
                                            <div class="articleBlockGrey">
                                            <ul>
                                                <p>SQL&gt;&nbsp;select&nbsp;to_char(created,&#168;yyyy-mm-dd&nbsp;hh24:mi:ss&#168;)&nbsp;from&nbsp;jss_1; </p>
                                                <p>TO_CHAR(CREATED,&#168;YY </p>
                                                <p>------------------- </p>
                                                <p>2009-08-25&nbsp;12:49:29 </p>
                                                2009-08-25&nbsp;13:21:21 </ul>
                                                </div>
                                                <p>　　多了一条记录，说明job已经被自动触发。 </p>
                                                <p>　　最后再补充一句，基于event的job不能通过DBMS_SCHEDULER.RUN_JOB过程执行，否则会触发ORA-00942:&nbsp;table&nbsp;or&nbsp;view&nbsp;does&nbsp;not&nbsp;exist错误。 </p>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303630.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:15 <a href="http://www.blogjava.net/javaex/articles/303630.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (7)使用Events之Scheduler抛出的Events 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-using-scheduler-events.shtml</title><link>http://www.blogjava.net/javaex/articles/303629.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:14:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303629.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303629.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303629.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303629.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303629.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(7)使用Events之Scheduler抛出的Events</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-8-26</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h2>四、使用Events </h2>
            <p>　　Event直译对应的中文解释是指事件，不过单纯讲事件毕竟太抽象了，举个示例来形容吧。A(对应某个应用程序，或者是ORACLE中的进程)在干活时突然眉头一皱说道，不好，前方有情况，这可怎么办！这时，只见它认真想了想，过了一会儿脸上一喜说道：有了，俗话说早请示啊晚汇报，出现情况要找领导，赶紧给领导发消息呗！于是B(也是对应某个应用或ORACLE进程)就收到了一条A发过来的"前方有XX情况"的消息，这个过程就叫EVENT(含A发消息以及B接收消息)。 </p>
            <p>　　SCHEDULER 中有两种触发EVENT的情况： </p>
            <ul>
                <li>Scheduler 触发的Events
                <p>Scheduler 中触发的Events，一般是说当前schduler中job的状态发生修改，类似job启动，或者运行结束，或者达到运行时间等诸如此类的动作，都能够抛出一个EVENT，接收到EVENT的applicate就可以根据这些信息进行适当的处理。 </p>
                <p>比如说，由于系统太过于繁忙，超出job启动时间后30分钟，job仍然没能顺利启动，那么这个时候，Scheduler就可以抛出一条EVENT给外部的应用，以便外部应用能够及时通知DBA，进行处理。 </p>
                <li>application 触发的Events
                <p>外部的应用也可以触发Events，并且由Scheduler来接收并处理这一类型的Events。所谓Scheduler处理EVENT就是指Scheduler启动相应的job来执行相关操作，这类job在创建时专门声明了event的处理，这样当接收到EVENT时，这类job就会启动。 </p>
                </li>
            </ul>
            <p>　　Scheduler 使用Oracle高级队列来抛出以及销毁Events。当抛出Schduler触发的Events时，Scheduler将消息入队到默认的event队列，application则通过检查该队列来处理Events。当抛出application触发的Events时，application将消息入队到处理job对应的队列中。 </p>
            <p>　　下面我们也按照这两个类型来介绍Scheduler中的Events。 </p>
            <h3>4.1&nbsp;Scheduler抛出的Events </h3>
            <p>　　前面说了，Scheduler抛出的Events一般是指job状态改变时触发的，那么是不是说只要job状态发生了改变，就会触发Events，其实并非如此，因为默认情况下，job是不触发Events的。 </p>
            <p>　　Scheduler 中的job有一个属性叫raise_events，专门用来设置job触发Events的条件，该属性在CREATE_JOB时不能执行，因此默认情况下该属性不会赋值，自然也就不会触发EVENT。要设置raise_events属性，只能是在job创建完成后，通过SET_ATTRIBUTE过程修改job的raise_events属性。 </p>
            <p>　　例如，修改前面创建的job-，启用raise_events属性，执行语句如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>SQL&gt;&nbsp;BEGIN </p>
                <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.SET_ATTRIBUTE(&#168;INSERT_TEST_TBL&#168;,&nbsp;&#168;raise_events&#168;,&nbsp;&nbsp;DBMS_SCHEDULER.JOB_ALL_EVENTS) </p>
                <p>&nbsp;&nbsp;3&nbsp;&nbsp;END; </p>
                <p>&nbsp;&nbsp;4&nbsp;&nbsp;/ </p>
                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                </div>
                <p>　　上述示例中指定的raise_events属性的属性值DBMS_SCHEDULER.JOB_ALL_EVENTS，就是抛出Events的触发条件。 </p>
                <p>　　触发Events的有下列的类型，分别代表不同的操作： </p>
                <ul>
                    <li>job_started ：JOB启动；
                    <li>job_succeeded ：JOB成功结束；
                    <li>job_failed ：JOB执行失败；
                    <li>job_broken ：JOB被置为BROKEN状态；
                    <li>job_completed ：JOB达到最大运行次数，或者运行的结束日期；
                    <li>job_stopped ：JOB被STOP_JOB过程置为停止执行的状态；
                    <li>job_sch_lim_reached ：Job的schedule达到限定值；
                    <li>job_disabled ：JOB被置于DISABLE状态；
                    <li>job_chain_stalled ：运行于chain的JOB被置于CHAIN_STALLED状态；
                    <li>job_all_events ：含上述提到的所有类型；
                    <li>job_run_completed ：由于Job运行出错、成功结束或被手动停止。 </li>
                </ul>
                <p>　　起用raise_events后，Scheduler就会按照设定的触发条件，当达到触发条件时，即会抛出事件信息到SYS.SCHEDULER$_EVENT_QUEUE队列。 </p>
                <p>　　例如，手动执行一次INSERT_TEST_TBL，看看是否向队列中记录信息，操作如下： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.run_job(&#168;INSERT_TEST_TBL&#168;); </p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <p>　　执行下列脚本，出队数据： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;set&nbsp;serveroutput&nbsp;on </p>
                        <p>SQL&gt;&nbsp;DECLARE </p>
                        <p>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;l_dequeue_options&nbsp;&nbsp;&nbsp;&nbsp;DBMS_AQ.dequeue_options_t; </p>
                        <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;l_message_properties&nbsp;DBMS_AQ.message_properties_t; </p>
                        <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;l_message_handle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RAW(16); </p>
                        <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;l_queue_msg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sys.scheduler$_event_info; </p>
                        <p>&nbsp;&nbsp;6&nbsp;&nbsp;BEGIN </p>
                        <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;l_dequeue_options.consumer_name&nbsp;:=&nbsp;&#168;TEST&#168;; </p>
                        <p>&nbsp;&nbsp;8 </p>
                        <p>&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;DBMS_AQ.dequeue(queue_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;SYS.SCHEDULER$_EVENT_QUEUE&#168;, </p>
                        <p>&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dequeue_options&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;l_dequeue_options, </p>
                        <p>&nbsp;11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message_properties&nbsp;=&gt;&nbsp;l_message_properties, </p>
                        <p>&nbsp;12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;payload&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;l_queue_msg, </p>
                        <p>&nbsp;13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msgid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;l_message_handle); </p>
                        <p>&nbsp;14&nbsp;&nbsp;&nbsp;&nbsp;COMMIT; </p>
                        <p>&nbsp;15 </p>
                        <p>&nbsp;16&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;event_type&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.event_type); </p>
                        <p>&nbsp;17&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;object_owner&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.object_owner); </p>
                        <p>&nbsp;18&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;object_name&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.object_name); </p>
                        <p>&nbsp;19&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;event_timestamp:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.event_timestamp); </p>
                        <p>&nbsp;20&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;error_code&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.error_code); </p>
                        <p>&nbsp;21&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;event_status&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.event_status); </p>
                        <p>&nbsp;22&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;log_id&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.log_id); </p>
                        <p>&nbsp;23&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;run_count&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.run_count); </p>
                        <p>&nbsp;24&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;failure_count&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.failure_count); </p>
                        <p>&nbsp;25&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&#168;retry_count&nbsp;:&nbsp;&#168;&nbsp;||&nbsp;l_queue_msg.retry_count); </p>
                        <p>&nbsp;26&nbsp;&nbsp;END; </p>
                        <p>&nbsp;27&nbsp;&nbsp;/ </p>
                        <p>event_type&nbsp;:&nbsp;JOB_STARTED </p>
                        <p>object_owner&nbsp;:&nbsp;TEST </p>
                        <p>object_name&nbsp;:&nbsp;INSERT_TEST_TBL </p>
                        <p>event_timestamp:&nbsp;25-AUG-09&nbsp;12.49.29.558758&nbsp;PM&nbsp;+08:00 </p>
                        <p>error_code&nbsp;:&nbsp;0 </p>
                        <p>event_status&nbsp;:&nbsp;1 </p>
                        <p>log_id&nbsp;: </p>
                        <p>run_count&nbsp;:&nbsp;1 </p>
                        <p>failure_count&nbsp;:&nbsp;0 </p>
                        <p>retry_count&nbsp;:&nbsp;0 </p>
                        PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                        </div>
                        <p>　　从返回的信息可以看到，event的类型为JOB_STARTED，表示JOB启动。实际上job:INSERT_TEST_TBL执行一次至少会向队列中插入两条event信息，一条为JOB_STARTED，一条则为JOB_SUCCEEDED(也可能是JOB_FAILED)，这里不详细演示，感兴趣的朋友不妨自行测试。 </p>
                        <div class="articleBlockGrey">
                        <ul>提示：SYS.SCHEDULER$_EVENT_QUEUE队列基于SYS.SCHEDULER$_EVENT_QTAB队列表，因此查询SYS.SCHEDULER$_EVENT_QTAB也可以获取上述的信息。 </ul>
                            </div>
                            <p>　　SYS.SCHEDULER$_EVENT_QUEUE 是一个固定队列，实际应用的过程中，DBA应该根据实际情况，将该表访问权限授予相关用户，以便顺利出队该队列中的events信息。 </p>
                            <p>　　另外，友情提醒，默认情况下Scheduler仅保留最近24小时的Events信息，如果希望修改该设置的话，可以通过SET_SCHEDULER_ATTRIBUTE过程，修改scheduler的event_expiry_time属性，该项属性的属性值以秒为单位。</p>
                            </td>
                        </tr>
                    </tbody>
                </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303629.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:14 <a href="http://www.blogjava.net/javaex/articles/303629.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (6)设置Repeat Interval参数 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-repeat_interval.shtml</title><link>http://www.blogjava.net/javaex/articles/303627.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:12:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303627.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303627.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303627.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303627.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303627.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(6)设置Repeat Interval参数</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-8-18</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h3>3.3 设置Repeat&nbsp;Interval </h3>
            <p>　　Job 和Schedule中REPEAT_INTERVAL参数都是用来控制执行的频率或周期，虽然说周期是一个时间性概念，不过REPEAT_INTERVAL指定的时候并不是一个时间值，而是由一组关键字描述的时间。 </p>
            <p>　　除了前面介绍Job和Schedule的REPEAT_INTERVAL参数时，提到该参数拥有FREQ以及INTERVAL两个关键字，其实除此之外，还有如BYMONTH、BYWEEKNO、BYYEARDAY、BYDATE等等参数，可以用来进行更精确的定义，比如通过BYMONTH关键字指定调度运行的月份，BYDAY指定调度在哪天运行等等。 </p>
            <p>　　REPEAT_INTERVAL 参数的详细语法如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>repeat_interval&nbsp;=&nbsp;regular_schedule&nbsp;|&nbsp;combined_schedule </p>
                <p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝ </p>
                <p>regular_schedule&nbsp;=&nbsp;frequency_clause </p>
                <p>[";"&nbsp;interval_clause]&nbsp;[";"&nbsp;bymonth_clause]&nbsp;[";"&nbsp;byweekno_clause] </p>
                <p>[";"&nbsp;byyearday_clause]&nbsp;[";"&nbsp;bydate_clause]&nbsp;[";"&nbsp;bymonthday_clause] </p>
                <p>[";"&nbsp;byday_clause]&nbsp;[";"&nbsp;byhour_clause]&nbsp;[";"&nbsp;byminute_clause] </p>
                <p>[";"&nbsp;bysecond_clause]&nbsp;[";"&nbsp;bysetpos_clause]&nbsp;[";"&nbsp;include_clause] </p>
                <p>[";"&nbsp;exclude_clause]&nbsp;[";"&nbsp;intersect_clause][";"&nbsp;periods_clause] </p>
                <p>[";"&nbsp;byperiod_clause] </p>
                <p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝ &nbsp; </p>
                <p>combined_schedule&nbsp;=&nbsp;schedule_list&nbsp;[";"&nbsp;include_clause] </p>
                <p>[";"&nbsp;exclude_clause]&nbsp;[";"&nbsp;intersect_clause] </p>
                <p>frequency_clause&nbsp;=&nbsp;"FREQ"&nbsp;"="&nbsp;(&nbsp;predefined_frequency&nbsp;|&nbsp;user_defined_frequency&nbsp;) </p>
                <p>predefined_frequency&nbsp;=&nbsp;"YEARLY"&nbsp;|&nbsp;"MONTHLY"&nbsp;|&nbsp;"WEEKLY"&nbsp;|&nbsp;"DAILY"&nbsp;|&nbsp; </p>
                <p>&nbsp;&nbsp;&nbsp;"HOURLY"&nbsp;|&nbsp;"MINUTELY"&nbsp;|&nbsp;"SECONDLY" </p>
                <p>user_defined_frequency&nbsp;=&nbsp;named_schedule </p>
                <p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝ </p>
                <p>interval_clause&nbsp;=&nbsp;"INTERVAL"&nbsp;"="&nbsp;intervalnum </p>
                <p>&nbsp;&nbsp;&nbsp;intervalnum&nbsp;=&nbsp;1&nbsp;through&nbsp;99 </p>
                <p>bymonth_clause&nbsp;=&nbsp;"BYMONTH"&nbsp;"="&nbsp;monthlist </p>
                <p>&nbsp;&nbsp;&nbsp;monthlist&nbsp;=&nbsp;monthday&nbsp;(&nbsp;","&nbsp;monthday)* </p>
                <p>&nbsp;&nbsp;&nbsp;month&nbsp;=&nbsp;numeric_month&nbsp;|&nbsp;char_month </p>
                <p>&nbsp;&nbsp;&nbsp;numeric_month&nbsp;=&nbsp;1&nbsp;|&nbsp;2&nbsp;|&nbsp;3&nbsp;...&nbsp;&nbsp;12 </p>
                <p>&nbsp;&nbsp;&nbsp;char_month&nbsp;=&nbsp;"JAN"&nbsp;|&nbsp;"FEB"&nbsp;|&nbsp;"MAR"&nbsp;|&nbsp;"APR"&nbsp;|&nbsp;"MAY"&nbsp;|&nbsp;"JUN"&nbsp;| </p>
                <p>&nbsp;&nbsp;&nbsp;"JUL"&nbsp;|&nbsp;"AUG"&nbsp;|&nbsp;"SEP"&nbsp;|&nbsp;"OCT"&nbsp;|&nbsp;"NOV"&nbsp;|&nbsp;"DEC" </p>
                <p>byweekno_clause&nbsp;=&nbsp;"BYWEEKNO"&nbsp;"="&nbsp;weeknumber_list </p>
                <p>&nbsp;&nbsp;&nbsp;weeknumber_list&nbsp;=&nbsp;weeknumber&nbsp;(&nbsp;","&nbsp;weeknumber)* </p>
                <p>&nbsp;&nbsp;&nbsp;weeknumber&nbsp;=&nbsp;[minus]&nbsp;weekno </p>
                <p>&nbsp;&nbsp;&nbsp;weekno&nbsp;=&nbsp;1&nbsp;through&nbsp;53 </p>
                <p>byyearday_clause&nbsp;=&nbsp;"BYYEARDAY"&nbsp;"="&nbsp;yearday_list </p>
                <p>&nbsp;&nbsp;&nbsp;yearday_list&nbsp;=&nbsp;yearday&nbsp;(&nbsp;","&nbsp;yearday)* </p>
                <p>&nbsp;&nbsp;&nbsp;yearday&nbsp;=&nbsp;[minus]&nbsp;yeardaynum </p>
                <p>&nbsp;&nbsp;&nbsp;yeardaynum&nbsp;=&nbsp;1&nbsp;through&nbsp;366 </p>
                <p>bydate_clause&nbsp;=&nbsp;"BYDATE"&nbsp;"="&nbsp;date_list </p>
                <p>&nbsp;&nbsp;&nbsp;date_list&nbsp;=&nbsp;date&nbsp;(&nbsp;","&nbsp;date)* </p>
                <p>&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;[YYYY]MMDD&nbsp;[&nbsp;offset&nbsp;|&nbsp;span&nbsp;] </p>
                <p>bymonthday_clause&nbsp;=&nbsp;"BYMONTHDAY"&nbsp;"="&nbsp;monthday_list </p>
                <p>&nbsp;&nbsp;&nbsp;monthday_list&nbsp;=&nbsp;monthday&nbsp;(&nbsp;","&nbsp;monthday)* </p>
                <p>&nbsp;&nbsp;&nbsp;monthday&nbsp;=&nbsp;[minus]&nbsp;monthdaynum </p>
                <p>&nbsp;&nbsp;&nbsp;monthdaynum&nbsp;=&nbsp;1&nbsp;through&nbsp;31 </p>
                <p>byday_clause&nbsp;=&nbsp;"BYDAY"&nbsp;"="&nbsp;byday_list </p>
                <p>&nbsp;&nbsp;&nbsp;byday_list&nbsp;=&nbsp;byday&nbsp;(&nbsp;","&nbsp;byday)* </p>
                <p>&nbsp;&nbsp;&nbsp;byday&nbsp;=&nbsp;[weekdaynum]&nbsp;day </p>
                <p>&nbsp;&nbsp;&nbsp;weekdaynum&nbsp;=&nbsp;[minus]&nbsp;daynum </p>
                <p>&nbsp;&nbsp;&nbsp;daynum&nbsp;=&nbsp;1&nbsp;through&nbsp;53&nbsp;/*&nbsp;if&nbsp;frequency&nbsp;is&nbsp;yearly&nbsp;*/ </p>
                <p>&nbsp;&nbsp;&nbsp;daynum&nbsp;=&nbsp;1&nbsp;through&nbsp;5&nbsp;&nbsp;/*&nbsp;if&nbsp;frequency&nbsp;is&nbsp;monthly&nbsp;*/ </p>
                <p>&nbsp;&nbsp;&nbsp;day&nbsp;=&nbsp;"MON"&nbsp;|&nbsp;"TUE"&nbsp;|&nbsp;"WED"&nbsp;|&nbsp;"THU"&nbsp;|&nbsp;"FRI"&nbsp;|&nbsp;"SAT"&nbsp;|&nbsp;"SUN" </p>
                <p>byhour_clause&nbsp;=&nbsp;"BYHOUR"&nbsp;"="&nbsp;hour_list </p>
                <p>&nbsp;&nbsp;&nbsp;hour_list&nbsp;=&nbsp;hour&nbsp;(&nbsp;","&nbsp;hour)* </p>
                <p>&nbsp;&nbsp;&nbsp;hour&nbsp;=&nbsp;0&nbsp;through&nbsp;23 </p>
                <p>byminute_clause&nbsp;=&nbsp;"BYMINUTE"&nbsp;"="&nbsp;minute_list </p>
                <p>&nbsp;&nbsp;&nbsp;minute_list&nbsp;=&nbsp;minute&nbsp;(&nbsp;","&nbsp;minute)* </p>
                <p>&nbsp;&nbsp;&nbsp;minute&nbsp;=&nbsp;0&nbsp;through&nbsp;59 </p>
                <p>bysecond_clause&nbsp;=&nbsp;"BYSECOND"&nbsp;"="&nbsp;second_list </p>
                <p>&nbsp;&nbsp;&nbsp;second_list&nbsp;=&nbsp;second&nbsp;(&nbsp;","&nbsp;second)* </p>
                <p>&nbsp;&nbsp;&nbsp;second&nbsp;=&nbsp;0&nbsp;through&nbsp;59 </p>
                <p>bysetpos_clause&nbsp;=&nbsp;"BYSETPOS"&nbsp;"="&nbsp;setpos_list </p>
                <p>&nbsp;&nbsp;&nbsp;setpos_list&nbsp;=&nbsp;setpos&nbsp;(","&nbsp;setpos)* </p>
                <p>&nbsp;&nbsp;&nbsp;setpos&nbsp;=&nbsp;[minus]&nbsp;setpos_num </p>
                <p>&nbsp;&nbsp;&nbsp;setpos_num&nbsp;=&nbsp;1&nbsp;through&nbsp;9999 </p>
                <p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝ </p>
                <p>include_clause&nbsp;=&nbsp;"INCLUDE"&nbsp;"="&nbsp;schedule_list </p>
                <p>exclude_clause&nbsp;=&nbsp;"EXCLUDE"&nbsp;"="&nbsp;schedule_list </p>
                <p>intersect_clause&nbsp;=&nbsp;"INTERSECT"&nbsp;"="&nbsp;schedule_list </p>
                <p>schedule_list&nbsp;=&nbsp;schedule_clause&nbsp;(","&nbsp;schedule_clause)* </p>
                <p>schedule_clause&nbsp;=&nbsp;named_schedule&nbsp;[&nbsp;offset&nbsp;] </p>
                <p>named_schedule&nbsp;=&nbsp;[schema&nbsp;"."]&nbsp;schedule </p>
                <p>periods_clause&nbsp;=&nbsp;"PERIODS"&nbsp;"="&nbsp;periodnum </p>
                <p>byperiod_clause&nbsp;=&nbsp;"BYPERIOD"&nbsp;"="&nbsp;period_list </p>
                <p>period_list&nbsp;=&nbsp;periodnum&nbsp;(","&nbsp;periodnum)* </p>
                <p>periodnum&nbsp;=&nbsp;1&nbsp;through&nbsp;100 </p>
                <p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝ </p>
                <p>offset&nbsp;=&nbsp;("+"&nbsp;|&nbsp;"-")&nbsp;["OFFSET:"]&nbsp;duration_val </p>
                <p>span&nbsp;=&nbsp;("+"&nbsp;|&nbsp;"-"&nbsp;|&nbsp;"^")&nbsp;"SPAN:"&nbsp;duration_val </p>
                <p>duration_val&nbsp;=&nbsp;dur-weeks&nbsp;|&nbsp;dur_days </p>
                <p>dur_weeks&nbsp;=&nbsp;numofweeks&nbsp;"W" </p>
                <p>dur_days&nbsp;=&nbsp;numofdays&nbsp;"D" </p>
                <p>numofweeks&nbsp;=&nbsp;1&nbsp;through&nbsp;53 </p>
                <p>numofdays&nbsp;=&nbsp;1&nbsp;through&nbsp;376 </p>
                minus&nbsp;=&nbsp;"-" </ul>
                </div>
                <p>　　这个语法形式看起来复杂无比，其实实用起来很简单，之所以看起来复杂，是因为其功能太过灵活(之前的<a title="点击阅读三思笔记---诙谐幽默简单易读的ORACLE学习文章" href="http://www.5ienet.com/note" target="_blank">三思</a>系列笔记中，已经阐述过灵活与复杂的关系)，这里不准备逐条解释每一个语法细节，下面将着重通过一些常用设置，希望能够更有助于广大同仁的理解。 </p>
                <p>　　例如：设置任务仅在周5的时候运行： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=DAILY;&nbsp;BYDAY=FRI&#168;; </p>
                    <p>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=WEEKLY;&nbsp;BYDAY=FRI&#168;; </p>
                    REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=YEARLY;&nbsp;BYDAY=FRI&#168;; </ul>
                    </div>
                    <p>　　上述三条语句虽然指定的关键字小有差异，不过功能相同。 </p>
                    <p>　　设置任务隔一周运行一次，并且仅在周5运行： </p>
                    <div class="articleBlockGrey">
                    <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=WEEKLY;&nbsp;INTERVAL=2;&nbsp;BYDAY=FRI&#168;; </ul>
                        </div>
                        <p>　　设置任务在当月最后一天运行： </p>
                        <div class="articleBlockGrey">
                        <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=MONTHLY;&nbsp;BYMONTHDAY=-1&#168;; </ul>
                            </div>
                            <p>　　设置任务在3月10日运行： </p>
                            <div class="articleBlockGrey">
                            <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=YEARLY;&nbsp;BYMONTH=MAR;&nbsp;BYMONTHDAY=10&#168;;
                                <p>&nbsp;</p>
                                REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=YEARLY;&nbsp;BYDATE=0310&#168;; </ul>
                                </div>
                                <p>　　上述两条语句功能相同。 </p>
                                <p>　　设置任务每10隔天运行： </p>
                                <div class="articleBlockGrey">
                                <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=DAILY;&nbsp;INTERVAL=10&#168;; </ul>
                                    </div>
                                    <p>　　设置任务在每天的下午4、5、6点时运行： </p>
                                    <div class="articleBlockGrey">
                                    <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=DAILY;&nbsp;BYHOUR=16,17,18&#168;; </ul>
                                        </div>
                                        <p>　　设置任务在每月29日运行： </p>
                                        <div class="articleBlockGrey">
                                        <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=MONTHLY;&nbsp;BYMONTHDAY=29&#168;; </ul>
                                            </div>
                                            <p>　　设置任务在每年的最后一个周5运行： </p>
                                            <div class="articleBlockGrey">
                                            <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=YEARLY;&nbsp;BYDAY=-1FRI&#168;; </ul>
                                                </div>
                                                <p>　　设置任务每隔50个小时运行： </p>
                                                <div class="articleBlockGrey">
                                                <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;FREQ=HOURLY;&nbsp;INTERVAL=50&#168;; </ul>
                                                    </div>
                                                    <p>　　另外，你是否在怀念常规job中设置interval的简便，虽然功能较弱，但是设置操作非常简单，无须懊恼，其实SCHEDULER中的REPEAT_INTERVAL也完全可以按照那种方式设置，前面都说了，REPEAT_INTERVAL实际上是指定周期，直接指定一个时间值，当然也是周期喽。 </p>
                                                    <p>　　比如说，设置任务每天执行一次，也可以设置REPEAT_INTERVAL参数值如下： </p>
                                                    <div class="articleBlockGrey">
                                                    <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;trunc(sysdate)+1&#168; </ul>
                                                        </div>
                                                        <p>　　又比如设置任务每周执行一次： </p>
                                                        <div class="articleBlockGrey">
                                                        <ul>REPEAT_INTERVAL&nbsp;=&gt;&nbsp;&#168;trunc(sysdate)+7&#168; </ul>
                                                            </div>
                                                            <p>　　不过需要注意，这种方式仅用于创建SCHEDULER中jobs时使用，不能用于schedule。 </p>
                                                            </td>
                                                        </tr>
                                                    </tbody>
                                                </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303627.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:12 <a href="http://www.blogjava.net/javaex/articles/303627.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (5)Schedules调度Programs执行的Jobs 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-schedule-job-execute.shtml</title><link>http://www.blogjava.net/javaex/articles/303626.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:10:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303626.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303626.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303626.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303626.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303626.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(5)Schedules调度Programs执行的Jobs</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-8-17</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h3>3.2&nbsp;Schedules调度Programs执行的Jobs </h3>
            <p>　　通过schedule调度program的执行的job，看到这样的形容是不是让你彻底晕头了，就说明你还是没搞明白10g中SCHEDULERS特性管理的jobs的含意，让<a title="点击阅读三思笔记---诙谐幽默简单易读的ORACLE学习文章" href="http://www.5ienet.com/note" target="_blank">三思</a>更直白地给你描述描述。10g版本中SCHEDULER将JOB分成了多个部分，program负责做什么，schedule负责啥时候做，job就简单了，一个字：做。 </p>
            <p>　　前面几个小节，<a title="点击阅读三思笔记---诙谐幽默简单易读的ORACLE学习文章" href="http://www.5ienet.com/note" target="_blank">三思</a>已经分别演示了创建管理Jobs，创建管理Programs以及创建和管理Schedules，下面我们通过实例来演示，如何创建通过schedule调度program的执行的job吧。 </p>
            <p>　　首先，创建一个program，操作如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>SQL&gt;&nbsp;BEGIN </p>
                <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.CREATE_PROGRAM&nbsp;( </p>
                <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;my_program1&#168;, </p>
                <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;/bin/date&#168;, </p>
                <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;EXECUTABLE&#168;, </p>
                <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enabled&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;TRUE); </p>
                <p>&nbsp;&nbsp;7&nbsp;&nbsp;END; </p>
                <p>&nbsp;&nbsp;8&nbsp;&nbsp;/ </p>
                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                </div>
                <p>　　通过上述语句，我们定义了一个program，执行操作系统命令date，并输入到dt.log文件中。 </p>
                <p>　　接下来定义一个schedule，操作如下： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;begin </p>
                    <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.CREATE_SCHEDULE&nbsp;( </p>
                    <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;schedule_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;my_first_schedule&#168;, </p>
                    <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;start_date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;SYSDATE, </p>
                    <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;repeat_interval&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;FREQ= DAILY ;&nbsp;INTERVAL=1&#168;, </p>
                    <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;comments&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;Every&nbsp;1&nbsp;weeks&#168;); </p>
                    <p>&nbsp;&nbsp;7&nbsp;&nbsp;END; </p>
                    <p>&nbsp;&nbsp;8&nbsp;&nbsp;/ </p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <p>　　定义调试为每周执行一次。此处repeat_interval可根据实现情况进行修改。 </p>
                    <p>　　最后，创建job，按照指定的schedule，执行program，操作如下： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;BEGIN </p>
                        <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.CREATE_JOB&nbsp;( </p>
                        <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;execOScmd&#168;, </p>
                        <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_program1&#168;, </p>
                        <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;schedule_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;&#168;my_first_schedule&#168;, </p>
                        <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enabled&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;true); </p>
                        <p>&nbsp;&nbsp;7&nbsp;&nbsp;END; </p>
                        <p>&nbsp;&nbsp;8&nbsp;&nbsp;/ </p>
                        PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                        </div>
                        <p>　　创建job时，start_date,repeat_interval,job_action等均无须指定，因为这些参数将由program和schedule来控制。 </p>
                        <p>　　这样，操作完成后，ORACLE就会自动定时(当前设置为每周执行一次)program中定义的操作。 </p>
                        <p>　　要查看当前的执行情况，通过*_scheduler_job_run_details即可查询(*_scheduler_job_log也可以，不过该视图中信息不如detail中全面)。例如，查看刚刚创建的"EXECOSCMD"任务的执行情况，执行命令如下： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;select&nbsp;log_id,&nbsp;log_date,&nbsp;status,&nbsp;additional_info </p>
                            <p>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;user_scheduler_job_run_details </p>
                            <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;where&nbsp;job_name&nbsp;=&nbsp;&#168;EXECOSCMD&#168; </p>
                            <p>&nbsp;&nbsp;4&nbsp;&nbsp;; </p>
                            <p>&nbsp;&nbsp;&nbsp;&nbsp;LOG_ID&nbsp;LOG_DATE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STATUS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADDITIONAL_INFO </p>
                            <p>----------&nbsp;--------------------&nbsp;----------&nbsp;------------------------------ </p>
                            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13760&nbsp;17-AUG-09&nbsp;02.47.53.7&nbsp;SUCCEEDED </p>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;34050&nbsp;PM&nbsp;+08:00 </ul>
                            </div>
                            <p>　　看完这个示例之后，你是否对10g中的SCHEDULER特性多了些了解呢？千万表自满，SCHEDULER特性的功能还多着哪，接着往下看吧。 </p>
                            </td>
                        </tr>
                    </tbody>
                </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303626.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:10 <a href="http://www.blogjava.net/javaex/articles/303626.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (4)使用和管理Schedules 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-create-schedule.shtml</title><link>http://www.blogjava.net/javaex/articles/303624.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:09:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303624.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303624.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303624.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303624.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(4)使用和管理Schedules</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-8-13</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h2>三、使用Schedules </h2>
            <p>　　10g 中新推出的SCHEDULER可能确实会让很多初接触的朋友感觉晕头晕脑，相比之前的jobs，SCHEDULER中新增的概念太多。比如说jobs，仍然可以理解成之前版本中的jobs，不过功能更加强大(注意10g中也仍然可以使用普通jobs，这是废话，相信看本篇文章的朋友目前应该还是这样在用)，比如说program，指的是运行的程序(把要做什么单提出来了)，比如说schedule，我将其翻译为调度(job我翻译为任务)，定义执行的频率或者说周期。 </p>
            <h3>3.1&nbsp; 创建和管理Schedule s </h3>
            <p>　　Schedule ，中文直译的话应该理解成调度，从名字来看，它是一个逻辑实体(逻辑，还实体，好矛盾)，就是说当创建了schedule之后，数据库中就肯定存在这一对象，只不过这一对象是用来描述job的执行周期。 </p>
            <p>　　创建schedule可以通过DBMS_SCHEDULER.CREATE_SCHEDULE过程，该过程支持的参数如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>SQL&gt;&nbsp;desc&nbsp;dbms_scheduler.create_schedule; </p>
                <p>Parameter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                <p>---------------&nbsp;------------------------&nbsp;----&nbsp;--------&nbsp; </p>
                <p>SCHEDULE_NAME&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>START_DATE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIMESTAMP&nbsp;WITH&nbsp;TIME&nbsp;ZONE&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>REPEAT_INTERVAL&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>END_DATE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIMESTAMP&nbsp;WITH&nbsp;TIME&nbsp;ZONE&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                COMMENTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </ul>
                </div>
                <p>　　各参数分别代表含意如下： </p>
                <ul>
                    <li>SCHEDULE_NAME ：指定schedule名称，注意名称不能重复。
                    <li>START_DATE ：指定该调度的开始时间，可为空，当为空时表示该调度暂不起用。
                    <li>REPEAT_INTERVAL ：指定调度的执行频率或周期。
                    <li>END_DATE ：指定调度的结束时间，可为空，为空时就表示该调度将一直进行。
                    <li>COMMENTS ：注释信息。 </li>
                </ul>
                <p>　　这其中，比较有技术含量的是REPEAT_INTERVAL参数，对于这个参数大家应该不会太陌生，因为前面介绍Jobs，也曾经提到过同名的参数，Schedules中的REPEAT_INTERVAL参数和Jobs中的REPEAT_INTERVAL参数功能完全相同，甚至参数格式也一模一样。 </p>
                <p>　　REPEAT_INTERVAL 参数的语法结构要复杂的多。其中最重要的是FREQ和INTERVAL两个关键字。 </p>
                <ul>
                    <li>FREQ 关键字用来指定间隔的时间周期，可选参数有：YEARLY,&nbsp;MONTHLY,&nbsp;WEEKLY,&nbsp;DAILY,&nbsp;HOURLY,&nbsp;MINUTELY,&nbsp;and&nbsp;SECONDLY，分别表示年、月、周、日、时、分、秒等单位。
                    <li>INTERVAL 关键字用来指定间隔的频繁，可指定的值的范围从1-99。 </li>
                </ul>
                <p>　　比如说，当指定REPEAT_INTERVAL=&gt;&#168;FREQ=DAILY;INTERVAL=1&#168;;就表示每天执行一次，如果将INTERVAL改为7就表示每7天执行一次，效果等同于FREQ=WEEKLY;INTERVAL=1。 </p>
                <p>　　下面，创建一个schedule，指定调度为每周一次的频率，执行脚本如下： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;begin </p>
                    <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.CREATE_SCHEDULE&nbsp;( </p>
                    <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;schedule_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;my_first_schedule&#168;, </p>
                    <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;start_date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;SYSDATE, </p>
                    <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;repeat_interval&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;FREQ=WEEKLY;&nbsp;INTERVAL=1&#168;, </p>
                    <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;comments&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;Every&nbsp;1&nbsp;weeks&#168;); </p>
                    <p>&nbsp;&nbsp;7&nbsp;&nbsp;END; </p>
                    <p>&nbsp;&nbsp;8&nbsp;&nbsp;/ </p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <p>　　查询当前已经创建的schedules，可以通过*_SCHEDULER_SCHEDULES视图(含DBA_,ALL_,USER_)，例如，查看当前用户拥有的schedules，执行语句如下： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;select&nbsp;schedule_name,repeat_interval&nbsp;from&nbsp;user_scheduler_schedules; </p>
                        <p>SCHEDULE_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REPEAT_INTERVAL </p>
                        <p>------------------------------&nbsp;------------------------------ </p>
                        MY_FIRST_SCHEDULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FREQ=WEEKLY;&nbsp;INTERVAL=1 </ul>
                        </div>
                        <p>　　如果要修改schedule属性的话，也是使用DBMS_SCHEDULER.SET_ATTRIBUTE过程，该过程的调用方式前面已经多次演示过，这里就不再重复举例了，仅说明一点，对于schedule来说，能够修改的属性包括：REPEAT_INTERVAL、COMMENTS、END_DATE、START_DATE以及EVENT_SPEC。 </p>
                        <p>　　至于删除schedule，再简单不过，执行DBMS_SCHEDULER.DROP_SCHEDULE过程即可，例如： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;EXEC&nbsp;DBMS_SCHEDULER.DROP_SCHEDULE(&#168;MY_FIRST_SCHEDULE&#168;); </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                            </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:09 <a href="http://www.blogjava.net/javaex/articles/303624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (3)使用Programs 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-programs.shtml</title><link>http://www.blogjava.net/javaex/articles/303623.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:08:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303623.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303623.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303623.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303623.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303623.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(3)使用Programs</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-8-7</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h2>二、使用Programs </h2>
            <p>　　在论坛中偶尔见过有人讨论如何在ORACLE中执行操作系统命令，或是ORACLE数据库外的应用。应该说在9i及之前的版本中，虽然说并非完全无法实现（其实还是有多种方式能够变相实现的），不过复杂的实现方式让DBA使劲了力，伤透了心，费劲了事儿。 </p>
            <p>　　进入10g版本之后，就完全不必如此费神，因为有了DBMS_SCHEDULER，因为有了PROGRAM。 </p>
            <h3>2.1&nbsp; 创建Programs </h3>
            <p>　　Scheduler 中的Program对象并不是常规意义上的"程序"或"应用"，而就是一个"对象"，由DBA定义的，具有执行某项功能的特殊对象。Program中实际执行的操作可以分为下列三种类型： </p>
            <ul>
                <li>PL/SQL&nbsp;BLOCK ：标准的pl/sql代码块；
                <li>STORED&nbsp;PROCEDURE ：编译好的PL/SQL存储过程，或者Java存储过程，以及外部的c子程序；
                <li>EXECUTEABLE ：ORACLE数据库之外的应用，比如操作系统命令等等。 </li>
            </ul>
            <p>　　创建Programs使用DBMS_SCHEDULER.CREATE_PROGRAM过程，该过程支持的参数如下： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>JSSWEB&gt; &nbsp;desc&nbsp;dbms_scheduler.create_program; </p>
                <p>Parameter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode&nbsp;Default?&nbsp; </p>
                <p>-------------------&nbsp;--------------&nbsp;----&nbsp;--------&nbsp; </p>
                <p>PROGRAM_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>PROGRAM_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>PROGRAM_ACTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>NUMBER_OF_ARGUMENTS&nbsp;BINARY_INTEGER&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                <p>ENABLED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOLEAN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
                OMMENTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IN&nbsp;&nbsp;&nbsp;Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </ul>
                </div>
                <p>　　如上所示，前三项为必选参数，各参数实际代表的意义如下： </p>
                <ul>
                    <li>PROGRAM_NAME ：指定一个program名称；
                    <li>PROGRAM_TYPE ：Program的类型，如前文中所述，Program支持三种类型；
                    <li>PROGRAM_ACTION ：实际执行的操作，应与前面PROGRAM_TYPE参数关联使用。比如说前面指定了PROGRAM_TYPE为"PLSQL_BLOCK"，那么此处要执行的action就应当是一段标准的pl/sql代码。如果前面指定PROGRAM_TYPE为"STORED_PROCEDURE"，那么此处要执行的action就应当是ORACLE中定义好的存储过程(含Java存储过程)，如果前面指定PROGRAM_TYPE为"EXECUTABLE"，那么此处就应该指定外部命令的命令行信息(含路径信息)；
                    <li>NUMBER_OF_ARGUMENTS ：指定支持的参数个数，默认值为0即没有参数。每个program最多能够支持255个参数，注意如果PROGRAM_TYPE设置为PLSQL_BLOCK，那么本参数自动忽略；
                    <li>ENABLED ：指定是否将创建的program置为有效状态，默认情况下为false。
                    <li>COMMENTS ：这个不用再说了吧，注释信息。 </li>
                </ul>
                <p>　　下面实际操作一下看看，PL/SQL或PROCEDURE没有挑战(ORACLE中直接即可调用)，咱们创建一下program，直接调用操作系统中的ls命令，操作如下： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red">-- 与三思有点不同</span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'">SQL&gt;&nbsp;BEGIN</span></span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'">DBMS_SCHEDULER.CREATE_PROGRAM&nbsp;(</span></span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'">program_name&nbsp;=&gt;&nbsp;'IPCONFIG',</span></span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'">program_action&nbsp;=&gt;&nbsp;'C:\WINDOWS\system32\ipconfig.exe',</span></span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'">program_type&nbsp;=&gt;&nbsp;'EXECUTABLE',</span></span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'">enabled&nbsp;=&gt;&nbsp;TRUE);</span></span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="color: red"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'">END;</span></span></p>
                    <p class="p0" style="margin-top: 0pt; margin-bottom: 0pt; text-align: justify"><span style="font-weight: normal; font-size: 10.5pt; font-family: 'Arial-BoldMT-Identity-H'; mso-spacerun: 'yes'"><span style="color: red">/</span></span></p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <h3>2.2&nbsp; 管理Programs </h3>
                    <p>　　定义的program如何执行，这里先卖个关子，前面介绍CREATE_PROGRAM过程的参数时提到，每个program最多支持255个参数，要为program添加参数，可以通过DEFINE_PROGRAM_ARGUMENT过程。不过在为其添加参数前，要注意program的NUMBER_OF_ARGUMENTS指定的数量，如果该值为0，那么为其添加参数时就会报错。 </p>
                    <p>　　查询创建的program的信息，可以通过USER_SCHEDULER_PROGRAMS视图，例如： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;select&nbsp;program_name,program_type,program_action,number_of_arguments,enabled </p>
                        <p>&nbsp;&nbsp;2&nbsp;&nbsp;from&nbsp;user_scheduler_programs; </p>
                        <p>PROGRAM_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROGRAM_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROGRAM_ACTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NUMBER_OF_ARGUMENTS&nbsp;ENABL </p>
                        <p>--------------------&nbsp;----------------&nbsp;--------------------&nbsp;-------------------&nbsp;----- </p>
                        MY_PROGRAM1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXECUTABLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/bin/ls&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;FALSE </ul>
                        </div>
                        <p>　　由于前面创建program時並未指定NUMBER_OF_ARGUMENTS的值，因此我们这里需要首先修改该值为一个非0值，操作如下： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.set_attribute(&#168;my_program1&#168;,&#168;NUMBER_OF_ARGUMENTS&#168;,1); </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                            </div>
                            <p>　　没错，操作还是使用DBMS_SCHEDULER.SET_ATTRIBUTE过程。另外需要注意，program的NUMBER_OF_ARGUMENTS参数可是说想改就能改的，正常情况下该处理必须是在program处于enabled之前确认完毕，否则会触发ORA-27465错误，因此要修改program的参数之前，必须首先确保要修改program的enabled状态为false。 </p>
                            <p>　　那么对于已经处于enabled状态的program，如何修改其状态属性呢？其实很简单，前面操作jobs时使用的DBMS_SCHEDULER.DISABLE过程还记的吗？没错，该过程对于program同样好使，并且调用方式也完全一样，例如： </p>
                            <div class="articleBlockGrey">
                            <ul>
                                <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.disable(&#168;my_program1&#168;); </p>
                                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                </div>
                                <p>　　另外，如果希望将program置为enabled状态，执行DBMS_SCHEDULER.ENABLE过程即可，这里不再例举。 </p>
                                <p>　　接下来，就可以为刚刚创建的my_program1添加路径参数，操作如下： </p>
                                <div class="articleBlockGrey">
                                <ul>
                                    <p>SQL&gt;&nbsp;BEGIN </p>
                                    <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT&nbsp;( </p>
                                    <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;my_program1&#168;, </p>
                                    <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument_position&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;1, </p>
                                    <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;dirpath&#168;, </p>
                                    <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;VARCHAR2&#168;, </p>
                                    <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default_value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#168;/home/oracle&#168;); </p>
                                    <p>&nbsp;&nbsp;8&nbsp;&nbsp;END; </p>
                                    <p>&nbsp;&nbsp;9&nbsp;&nbsp;/ </p>
                                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                    </div>
                                    <p>　　查询为program定义的参数，可以通过USER_SCHEDULER_PROGRAM_ARGS视图，例如： </p>
                                    <div class="articleBlockGrey">
                                    <ul>
                                        <p>SQL&gt;&nbsp;select&nbsp;program_name,argument_name,argument_position,argument_type </p>
                                        <p>&nbsp;&nbsp;2&nbsp;&nbsp;default_value&nbsp;from&nbsp;user_scheduler_program_args; </p>
                                        <p>PROGRAM_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ARGUMENT_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ARGUMENT_POSITION&nbsp;DEFAULT_VALUE </p>
                                        <p>--------------------&nbsp;--------------------&nbsp;-----------------&nbsp;-------------------- </p>
                                        MY_PROGRAM1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DIRPATH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;VARCHAR2 </ul>
                                        </div>
                                        <p>　　删除program的argument操作也很简单，使用DROP_PROGRAM_ARGUMENT过程即可，例如： </p>
                                        <div class="articleBlockGrey">
                                        <ul>
                                            <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.drop_program_argument(&#168;my_program1&#168;,&#168;dirpath&#168;); </p>
                                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                            </div>
                                            <p>　　该过程第一个参数指定program名称，第二个参数指定定义的argument名称，当然此处也可以指定argument的位置，即前例视图返回结果中的 ARGUMENT_POSITION 列值。 </p>
                                            <p>　　要删除program的话就更简单了，使用DROP_PROGRAM过程即可，例如： </p>
                                            <div class="articleBlockGrey">
                                            <ul>
                                                <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.drop_program(&#168;my_program1&#168;); </p>
                                                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                                                </div>
                                                <p>　　当然啦，删除program的同时，也会删除该program对应的所有arguments。 </p>
                                                <p>　　实际上SCHEDULER中创建job时，也可以指定执行外部的程序。SCHEDULER中的Job更像是之前版本继承过来的JOBS，只不过10g中SCHEDULER管理的JOBS功能更加强大。Programs与Jobs不同的是，Jobs是定义好的，定时执行的任务，而Programs则是定义好的，等待被执行的对象。那么Programs是由谁来执行呢，不要走开，广告之后即将全面揭晓。 </p>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:08 <a href="http://www.blogjava.net/javaex/articles/303623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (2)使用Jobs之管理jobs 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-alter-job.shtml</title><link>http://www.blogjava.net/javaex/articles/303622.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:07:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303622.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303622.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303622.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303622.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(2)使用Jobs之管理jobs</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-7-31</td>
        </tr>
        <tr>
            <td class="articlebody">
            <h3>1.2&nbsp; 管理Jobs </h3>
            <h4>1.2.1&nbsp; 启用Jobs </h4>
            <p>　　前面创建JOB时，由于未显式的指定ENABLED参数，因此即使指定了START_DATE，不过默认情况下JOB不会自动执行。对于这种情况，DBMS_SCHEDULER包中提供了一个过程ENABLE，可以用来修改JOB的启用状态，调用方式非常简单，例如： </p>
            <div class="articleBlockGrey">
            <ul>
                <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.enable(&#168;INSERT_TEST_TBL&#168;); </p>
                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                </div>
                <h4>1.2.2&nbsp; 禁用Jobs </h4>
                <p>　　DBMS_SCHEDULER.ENABLE 仅用来将JOB(其实不仅仅对JOB有效，对于CHAIN、PROGRAM等也有效)的启用状态置为TRUE。如果想将其启用状态置为FALSE？简单，还有一个与该功能对应的过程：DBMS_SCHEDULER.DISABLE，例如： </p>
                <div class="articleBlockGrey">
                <ul>
                    <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.disable(&#168;INSERT_TEST_TBL&#168;); </p>
                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed. </ul>
                    </div>
                    <p>　　这两个过程仅用来重置对象的状态，因此均可以无限次执行，即使执行时对象已经被置为要指定的状态。 </p>
                    <h4>1.2.3&nbsp; 修改Jobs </h4>
                    <p>　　由于JOB的属性众多，难免时不时的可能会遇到需要修改的情况，比如说前面创建JOB时不小心，指定要执行的过程名输入错误(完全有可能，CREATE_JOB在创建时不会自动检查指定的过程是否有效，从这方面考虑，SCHEDULER不如普通JOB严谨哪)，这种情况下就必然涉及到对JOB的修改(或者说重定义)，没问题，DBMS_SCHEDULER包中专门提供了一个过程SET_ATTRIBUTE，可以用来修改任务的属性值。 </p>
                    <p>　　例如，修改刚刚创建的JOB：INSERT_TEST_TBL执行的过程，执行语句如下： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.set_attribute(&#168;INSERT_TEST_TBL&#168;,&#168;JOB_ACTION&#168;,&#168;P_ INSERT INTOTEST&#168;); </p>
                        PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed </ul>
                        </div>
                        <p>　　当然啦，我们这里执行的这条语句，执行跟没执行没有区别，此处仅做示例，大家表深究。 </p>
                        <p>　　SET_ATTRIBUTE 过程虽然仅有三个参数，不过能够修改的属性值可是不少，以下列举几个较常用到的： </p>
                        <ul>
                            <li>LOGGING_LEVEL ：指定对jobs执行情况记录的日志信息级别。
                            <p>SCHEDULER 管理的JOB对任务的执行情况专门进行了记录，同时用户还可以选择日志中记录信息的级别，有下列三种选择： </p>
                            <ul>
                                <li>DBMS_SCHEDULER.LOGGING_OFF ：关闭日志记录功能；
                                <li>DBMS_SCHEDULER.LOGGING_RUNS ：对任务的运行信息进行记录；
                                <li>DBMS_SCHEDULER.LOGGING_FULL ：记录任务所有相关信息，不仅有任务的运行情况，甚至连任务的创建、修改等也均将记入日志。 </li>
                            </ul>
                            <p>提示：查看SCHEDULER管理的JOB，可以通过USER_SCHEDULER_JOB_LOG和USER_SCHEDULER_JOB_RUN_DETAILS两个视图中查询 </p>
                            <li>RESTARTABLE ：指定jobs运行出错后，是否能够适时重启
                            <p>创建任务时如未明确指定，本参数默认情况下设置为FALSE，如果设置为TRUE，就表示当任务运行时出错，下次运行时间点到达时仍会启动，并且如果运行仍然出错，会继续重新运行，不过如果连接出错达到6次，该job就会停止。 </p>
                            <li>MAX_FAILURES ：指定jobs最大连续出错次数
                            <p>该参数值可指定的范围从1-1000000，默认情况下该参数设置为NULL，表示无限制。达到指定出错次数后，该job会被自动disable。 </p>
                            <li>MAX_RUNS ：指定jobs最大运行次数
                            <p>该参数值可指定的范围从1-1000000，默认情况下该参数设置为NULL，表示无限制(只是运行次数无限制，实际job会否继续运行，仍受制于end_date以及max_failures等参数的设置)。达到指定运行次数后，该job也将被自动disable，并且状态会被置为COMPLETED。 </p>
                            <li>JOB_TYPE ：指定job执行的任务的类型
                            <p>有四个可选值：&#168;PLSQL_BLOCK&#168;,&nbsp;&#168;STORED_PROCEDURE&#168;,&nbsp;&#168;EXECUTABLE&#168;,&nbsp;and&nbsp;&#168;CHAIN&#168;。 </p>
                            <li>JOB_ACTION ：指定job执行的任务
                            <p>这一参数所指定的值依赖于JOB_TYPE参数中的值，比如说JOB_TYPE设置为&#168;STORED_PROCEDURE&#168;，那么本参数值中指定的一定是ORACLE中的过程名。 </p>
                            <li>START_DATE ：指定job初次启动的时间
                            <li>END_DATE ：指定job停止运行的时间 </li>
                        </ul>
                        <p>　　本参数又与AUTO_DROP相关联，如果AUTO_DROP设置为TRUE的话，那么一旦job到达停止运行的时间，该job就会被自动删除，否则的话job任何存在，不过状态被修改为COMPLETED。 </p>
                        <p>　　除此之外，其它还包括MAX_RUN_DURATION，JOB_WEIGHT，INSTANCE_STICKINESS，STOP_ON_WINDOW_CLOSE，JOB_PRIORITY，SCHEDULE_LIMIT，PROGRAM_NAME，NUMBER_OF_ARGUMENTS，SCHEDULE_NAME，REPEAT_INTERVAL，JOB_CLASS，COMMENTS，AUTO_DROP，EVENT_SPEC，RAISE_EVENTS等等，这些参数所代表的意义此处不一一详述，感兴趣的朋友可以查阅相关官方文档，或者等待本系列文章的外传，黑黑。 </p>
                        <p>　　仅从这些可设置属性就可以看出，Scheduler管理的job确实非常灵活，上述提到了这些参数，均可以使用DBMS_SCHEDULER.SET_ATTRIBUTE过程进行设置。 </p>
                        <p>　　另外需要注意一点，除了用户手动创建的jobs之外，数据库在运行过程中也有可能自动创建jobs。对于这类jobs除非必要，否则不建议进行修改。至于如何区分jobs是用户创建，还是数据库自动创建，可以通过*_SCHEDULER_JOBS视图的SYSTEM列来确定，如果该列显示为TRUE，则表示由系统创建 </p>
                        <h4>1.2.4&nbsp; 执行Jobs </h4>
                        <p>　　虽然说jobs大多都应该是自动执行，不过经过前面的示例，大家想必也认识到了，并不是说创建了jobs它就会自动执行，是否能够真正自动执行并不是由你的主观意愿就能直接决定，而是由jobs自身的多个相关属性决定。 </p>
                        <p>　　关于jobs自动执行的话题相信看完前面的内容后，应该都知道如何设置，下面主要演示，如何手动调用jobs并执行，这其中，当然少不了DBMS_SCHEDULER包。例如，手动执行前面刚刚创建的job:INSERT_TEST_TBL： </p>
                        <div class="articleBlockGrey">
                        <ul>
                            <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.run_job(&#168;INSERT_TEST_TBL&#168;); </p>
                            PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed </ul>
                            </div>
                            <p>　　Jobs 每执行一次，无论成功或失败，均会在*_SCHEDULER_JOB_LOG中生成一条对应的记录(前提是LOGGING_LEVEL属性值未设置为DBMS_SCHEDULER.LOGGING_OFF)，同时，用户也可以通过*_SCHEDULER_JOB_RUN_DETAILS视图查询job执行的详细信息。 </p>
                            <h4>1.2.5&nbsp; 停止Jobs </h4>
                            <p>　　停止job可以使用DMBS_SCHEDULER.STOP_JOB过程，例如： </p>
                            <div class="articleBlockGrey">
                            <ul>
                                <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.stop_job(&#168;INSERT_TEST_TBL&#168;); </p>
                                PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed </ul>
                                </div>
                                <p>　　注意，STOP_JOB过程不仅仅是更新job的状态，而是停止当前正在执行的任务，如果你处理的任务当前未在运行的话，那么执行STOP_JOB过程，会触发ORA-27366错误。 </p>
                                <p>　　停止Jobs也会触发一条任务的日志信息，对于执行停止操作的job，其*_SCHEDULER_JOB_LOG视图的OPERATION会记录为&#168;STOPPED&#168;，ADDITIONAL_INFO列中记录的信息类似&#168;REASON="Stop&nbsp;job&nbsp;called&nbsp;by&nbsp;user:&nbsp;username"&#168;。 </p>
                                <h4>1.2.6&nbsp; 删除Jobs </h4>
                                <p>　　删除创建的job就比较简单了，直接执行DBMS_SCHEDULER.DROP_JOB过程即可，例如： </p>
                                <div class="articleBlockGrey">
                                <ul>
                                    <p>SQL&gt;&nbsp;exec&nbsp;dbms_scheduler.drop_job(&#168;INSERT_TEST_TBL&#168;); </p>
                                    PL/SQL&nbsp;procedure&nbsp;successfully&nbsp;completed </ul>
                                    </div>
                                    <p>　　删除jobs并不是修改该job中某个字段的标记值，而是直接删除其在数据字典中的字义，因此被删除的job如果未来发现仍然需要，只能重建，而无法通过其它方式快速恢复。不过，删除jobs的操作，并不会级联删除这些job曾经执行过的日志信息。 </p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:07 <a href="http://www.blogjava.net/javaex/articles/303622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面学习ORACLE Scheduler特性 (1)使用Jobs之创建jobs 转自三思 http://www.5ienet.com/note/html/scheduler/oracle-scheduler-create-job.shtml</title><link>http://www.blogjava.net/javaex/articles/303621.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 07:06:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303621.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303621.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303621.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303621.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="3" width="99%" align="center" border="0">
    <tbody>
        <tr>
            <td class="articletitle" align="center">(1)使用Jobs之创建jobs</td>
        </tr>
        <tr>
            <td align="center" height="30">[君三思] 2009-7-31</td>
        </tr>
        <tr>
            <td class="articlebody">
            <p>　　所谓出于job而胜于job，说的就是Oracle&nbsp;10g后的新特性Scheduler啦。在10g环境中，ORACLE建议使用Scheduler替换普通的job，来管理任务的执行。其实，将Scheduler描述成管理job的工具已经太过片面了，10G版本中新增的Scheduler绝不仅仅是创建任务这么简单。。。。 </p>
            <div class="articleBlockGrey">
            <ul>提示：ORACLE中管理Scheduler是通过DBMS_SCHEDULER包，本章也以此为切入点，通过详细介绍DBMS_SCHEDULER包的使用，来演示如何使用Scheduler。似乎本末倒置了，没关系，"<a title="点击阅读三思笔记---诙谐幽默简单易读的ORACLE学习文章" href="http://www.5ienet.com/note" target="_blank">三思</a>笔记"，俺的地盘俺做主。 </ul>
                </div>
                <h2>一、使用Jobs </h2>
                <p>　　所谓JOBS，其实就是Scheduler管理的一个(或多个)任务的执行调度。 </p>
                <h3>1.1&nbsp; 创建Jobs </h3>
                <p>　　通过DBMS_SCHEDULER包来创建Jobs，是使用其CREATE_JOB过程。在创建Job时，用户可以指定要执行的任务，调度信息(啥时候执行，执行周期，终止日期等)以及其它一些任务相关的属性。CREATE_JOB过程调用还是比较简单的，例如： </p>
                <div class="articleBlockGrey">&nbsp;</div>
                <div class="articleBlockGrey">
                <ul>
                    <p><span style="color: red">另外加上与三思有点不同</span></p>
                    <p><span style="color: red"><span style="color: red">-- Create table<br />
                    create table TEST<br />
                    (<br />
                    &nbsp; DATES DATE<br />
                    )</span></span></p>
                    <p><span style="color: red"></span>&nbsp;</p>
                    <p><span style="color: red"><span style="color: red">CREATE OR REPLACE PROCEDURE IT<br />
                    AS<br />
                    BEGIN<br />
                    insert into TEST VALUES(sysdate);<br />
                    END;</span></span></p>
                    <p>&nbsp;</p>
                    <p>SQL&gt;&nbsp;BEGIN </p>
                    <p>&nbsp;&nbsp;2&nbsp;&nbsp;DBMS_SCHEDULER.CREATE_JOB&nbsp;( </p>
                    <p>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;'INSERT_TEST_TBL', </p>
                    <p>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;job_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;'STORED_PROCEDURE', </p>
                    <p>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: red">job_action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;'SCOTT.IT',&nbsp; --与三思有所不同</span></p>
                    <p>&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;sysdate, </p>
                    <p>&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repeat_interval&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&nbsp;'FREQ=DAILY;INTERVAL=10'); </p>
                    <p>&nbsp;&nbsp;8&nbsp;&nbsp;END; </p>
                    <p>&nbsp;&nbsp;9&nbsp;&nbsp;/ </p>
                    PL/SQL&nbsp; 过程已成功完成。 </ul>
                    </div>
                    <p>　　事实上，有权限的话，用户也可以创建其它SCHEMA下的JOB，只需要在指定JOB_NAME时，按照schema.job_name的格式即可。注意哟，这种情况下创建的JOB，其CREATED与OWNER有可能并不相同的哟。 </p>
                    <p>　　当使用CREATE_JOB过程创建JOB时，可指定的参数值很多，只不过多数情况下用户仅指定部分参数即可满足需求。 </p>
                    <p>　　其中，上例中指定的参数，分别代表的含义如下： </p>
                    <ul>
                        <li>JOB_NAME ：指定任务的名称，必选值，注意要确保指定的名称唯一。
                        <li>JOB_TYPE ：任务执行的操作类型，必选值，有下列几个可选值：
                        <ul>
                            <li>PLSQL_BLOCK ：表示任务执行的是一个PL/SQL匿名块。
                            <li>STORED_PROCEDURE ：表示任务执行的是ORACLE过程(含PL/SQL&nbsp;PROCEDURE和JAVA&nbsp;PROCEDURE)，本例中正是指定这一参数值。
                            <li>EXECUTABLE ：表示任务执行的是一个外部程序，比如说操作系统命令。
                            <li>CHAIN ：表示任务执行的是一个CHAIN。 </li>
                        </ul>
                        <li>JOB_ACTION ：任务执行的操作，必选值，应与JOB_TYPE类型中指定的参数相匹配。
                        <p>比如说对于PL/SQL匿名块，此处就可以放置PL/SQL块的具体代表，类似DECLARE&nbsp;..&nbsp;BEGIN&nbsp;..END这类；如果是ORACLE过程，那么此处应该指定具体的过程名，注意由于任务执行，即使过程中有OUT之类参数，实际执行时也不会有输出的。 </p>
                        <li>START_DATE ：指定任务初次执行的时间，本参数可为空，当为空时，表示任务立刻执行，效果等同于指定该参数值为SYSDATE。
                        <li>REPEAT_INTERVAL ：指定任务执行的频率，比如多长时间会被触发再次执行。本参数也可以为空，如果为空的话，就表示当前设定的任务只执行一次。REPEAT_INTERVAL参数需要好好说说，因为这一参数与标准JOB中的INTERVAL参数有很大区别，相比之下，REPEAT_INTERVAL参数的语法结构要复杂的多。其中最重要的是FREQ和INTERVAL两个关键字。
                        <ul>
                            <li>FREQ 关键字用来指定间隔的时间周期，可选参数有：YEARLY,&nbsp;MONTHLY,&nbsp;WEEKLY,&nbsp;DAILY,&nbsp;HOURLY,&nbsp;MINUTELY,&nbsp;and&nbsp;SECONDLY，分别表示年、月、周、日、时、分、秒等单位。
                            <li>INTERVAL 关键字用来指定间隔的频繁，可指定的值的范围从1-99。 </li>
                        </ul>
                        <p>例如：REPEAT_INTERVAL=&gt;&#168;FREQ=DAILY;INTERVAL=1&#168;;表示每天执行一次，如果将INTERVAL改为7就表示每7天执行一次，效果等同于FREQ=WEEKLY;INTERVAL=1。 </p>
                        <p>一般来说，使用DBMS_SCHEDULER.CREATE_JOB创建一个JOB，至少需要指定上述参数中的前3项。除此之外，还可以在CREATE_JOB时，指定下列参数： </p>
                        <li>NUMBER_OF_ARGUMENTS ：指定该JOB执行时需要附带的参数的数量，默认值为0，注意当JOB_TYPE列值为PLSQL_BLOCK或CHAIN时，本参数必须设置为0，因为上述两种情况下不支持附带参数。
                        <li>END_DATE ：指定任务的过期时间，默认值为NULL。任务过期后，任务的STATE将自动被修改为COMPLETED，ENABLED被置为FALSE。如果该参数设置为空的话，表示该任务永不过期，将一直按照REPEAT_INTERVAL参数设置的周期重复执行，直到达到设置的MAX_RUNS或MAX_FAILURES值。
                        <li>JOB_CLASS ：指定任务关联的CLASS，默认值为DEFAULT_JOB_CLASS。关于JOB&nbsp;CLASS的信息就关注本系列的后续文章。
                        <li>ENABLED ：指定任务是否启用，默认值为FALSE。FALSE状态表示该任务并不会被执行，除非被用户手动调用，或者用户将该任务的状态修改为TRUE。
                        <li>AUTO_DROP ：当该标志被置为TRUE时，ORACLE会在满足条件时自动删除创建的任务
                        <ul>
                            <li>任务已过期；
                            <li>任务最大运行次数已达MAX_RUNS的设置值；
                            <li>任务未指定REPEAT_INTERVAL参数，仅运行一次； </li>
                        </ul>
                        <p>该参数的默认值即为TRUE。用户在执行CREATE_JOB过程时可以手动将该标志指定为FALSE，当参数值设置为FALSE时，即使满足上述提到的条件任务也不会被自动删除，这种情况下，唯一能够导致任务被删除的情况，就是用户主动调用DROP_JOB过程。 </p>
                        <li>COMMENTS ：设置任务的注释信息，默认值为NULL。 </li>
                    </ul>
                    <p>　　上面的例子创建了一个新的JOB，不过这个JOB与普通JOB不同哟，此时查询USER_JOBS视图是查不到刚刚创建的JOB的信息，因为这个JOB是SCHEDULER管理的JOB。要查询SCHEDULER管理的JOS，应该通过USER_SCHEDULER_JOBS(当然ALL_SCHEDULER_JOBS和DBA_SCHEDULER_JOBS也可以)，例如： </p>
                    <div class="articleBlockGrey">
                    <ul>
                        <p>SQL&gt;&nbsp;select&nbsp;job_name,job_type,job_action,to_char(start_date,&#168;yyyy-mm-dd&nbsp;hh24:mi:ss&#168;),repeat_interval,enabled,state&nbsp;from&nbsp;user_scheduler_jobs; </p>
                        <p>JOB_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JOB_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JOB_ACTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TO_CHAR(START_DATE,&nbsp;REPEAT_INTERVAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENABL&nbsp;STATE </p>
                        <p>--------------------&nbsp;----------------&nbsp;-------------------------&nbsp;-------------------&nbsp;------------------------------&nbsp;-----&nbsp;--------------- </p>
                        INSERT_TEST_TBL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STORED_PROCEDURE&nbsp;P_INSERTINTOTEST&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2009-07-27&nbsp;13:46:50&nbsp;FREQ=DAILY;INTERVAL=1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FALSE&nbsp;DISABLED </ul>
                        </div>
                        <p>　　不过，细心的盆友可能会发现，JOB虽然成功创建了，但却并未执行，这是怎么回事？其实原因很简单，还记的前面介绍CREATE_JOB过程时提到的ENABLED参数吗，当不显式指定时，该参数的默认值为false，JOB自然不会运行了。如果遇到这类情形，如何修改呢？请继续关注下一节。 </p>
                        </td>
                    </tr>
                </tbody>
            </table>
<img src ="http://www.blogjava.net/javaex/aggbug/303621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 15:06 <a href="http://www.blogjava.net/javaex/articles/303621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(20)--V$WAITSTAT 转自三思 http://junsansi.itpub.net/post/29894/295603</title><link>http://www.blogjava.net/javaex/articles/303587.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:46:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303587.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303587.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303587.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303587.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303587.html</trackback:ping><description><![CDATA[<p>学习动态性能表第20篇--V$WAITSTAT</p>
<p>第20篇--V$WAITSTAT 2007.6.15</p>
<p>　　本视图保持自实例启动所有的等待事件统计信息。常用于当你发现系统存在大量的"buffer busy waits"时据此做出适当调整。</p>
<p><strong>V$WAITSTAT中的常用列</strong><br />
CLASS：块类别<br />
WAITS：本类块的等待次数<br />
TIME：本类块的总等待时间</p>
<p><strong>等待发生的原因：</strong><br />
1.undo段头部：没有足够的回滚段<br />
2.数据段头部/数据段空闲列：空闲列争夺<br />
3.数据块冲突<br />
4.缓存存在大量的CR复制<br />
5.range检索时，索引列存在大量不连续<br />
6.全表检索的表有大量被删除记录<br />
7.高并发的读写块</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303587.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:46 <a href="http://www.blogjava.net/javaex/articles/303587.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(19)--V$UNDOSTAT 转自三思 http://junsansi.itpub.net/post/29894/295600</title><link>http://www.blogjava.net/javaex/articles/303585.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:45:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303585.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303585.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303585.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303585.html</trackback:ping><description><![CDATA[<p>学习动态性能表第19篇--V$UNDOSTAT</p>
<p>　　本视图监控当前实例中undo空间以及事务如何运行。并统计undo空间开销，事务开销以及实例可用的查询长度。</p>
<p><strong>V$UNDOSTAT中的常用列</strong><br />
Endtime：以10分钟为间隔的结束时间<br />
UndoBlocksUsed：使用的undo块总数<br />
TxnConcurrency：事务并发执行的最大数<br />
TxnTotal：在时间段内事务执行总数<br />
QueryLength：查询长度的最大值<br />
ExtentsStolen：在时间段内undo区必须从一个undo段转到另一个的次数<br />
SSTooOldError：在时间段内'Snapshot Too Old'错误发生的次数<br />
UNDOTSN：这段时间内最后活动的undo表空间ID</p>
<p>　　视图的第一行显示了当前时间段的统计，其它的每一条记录分别以每10分钟一个区间。24小时循环，一天最多144条记录。</p>
<p><strong>示例：</strong><br />
1.本例显示undo空间从16:27到之前24小时内的各项统计。<br />
SQL&gt;select * from v$undostat;</p>
<p>End-Time UndoBlocks TxnConcrcy TxnTotal QueryLen ExtentsStolen SSTooOldError<br />
-------- ---------- ---------- -------- -------- ------------- -------------<br />
16:07 252 15 1511 25 2 0<br />
16:00 752 16 1467 150 0 0<br />
15:50 873 21 1954 45 4 0<br />
15:40 1187 45 3210 633 20 1<br />
15:30 1120 28 2498 1202 5 0<br />
15:20 882 22 2002 55 0 0</p>
<p>在统计项收集过程中，undo消耗最高发生在15:30-15:40这个时间段。10分钟内有1187个undo块被占用(基本上每秒钟2个块)。同时，最高事务并发也是在相同的时间段，45个事务被并发执行。执行的最长查询(1202秒)是在15:20-15:30之间，需要注意的是查询实际上是15:00-15:10段即开始并直到15:20这个时间段。</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:45 <a href="http://www.blogjava.net/javaex/articles/303585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(18)--V$SYSTEM_EVENT  转自三思 http://junsansi.itpub.net/post/29894/295162</title><link>http://www.blogjava.net/javaex/articles/303584.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:43:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303584.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303584.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303584.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303584.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303584.html</trackback:ping><description><![CDATA[<p>学习动态性能表第18篇--V$SYSTEM_EVENT</p>
<p>　　本视图概括了实例各项事件的等待信息。v$session_wait显示了系统的当前等待项，v$system_event则提供了自实例启动后各个等待事件的概括。常用于获取系统等待信息的历史影象。而通过两个snapshot获取等待项增量，则可以确定这段时间内系统的等待项。</p>
<p><strong>V$SYSTEM_EVENT中的常用列</strong><br />
EVENT:等待事件名称<br />
TOTAL_WAITS：此项事件总等待次数<br />
TIME_WAITED：此项事件的总等待时间(单位：百分之一秒)<br />
AVERAGE_WAIT：此项事件的平均等待用时(单位：百分之一秒)(time_waited/total_waits)<br />
TOTAL_TIMEOUTS：此项事情总等待超时次数</p>
<p><strong>示例：</strong><br />
1.查看系统的各项等待，按总耗时排序<br />
SELECT event,total_waits waits,total_timeouts timeouts,<br />
time_waited total_time,average_wait avg<br />
FROM V$SYSTEM_EVENT<br />
ORDER BY 4 DESC;</p>
<p>比如，通过checkpoint completed、log file switch（checkpoint incomplete）可以查看检查点进程的性能。通过log file parallel write、log file switch completed可以查看联机重做日志文件的性能。通过log file switch（archiving needed）事件可以检查归档进程的性能。</p>
<p><strong>找出瓶颈：</strong><br />
1。通过Statspack列出空闲事件。<br />
2。检查不同事件的等待时间开销。<br />
3。检查每条等待记录的平均用时，因为某些等待事件(比较log file switch completion)可能周期性地发生，但发生时却造成了严重的性能损耗。</p>
 <img src ="http://www.blogjava.net/javaex/aggbug/303584.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:43 <a href="http://www.blogjava.net/javaex/articles/303584.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(17)--v$segstat&amp;v$segment_statistics 转自三思 http://junsansi.itpub.net/post/29894/295160</title><link>http://www.blogjava.net/javaex/articles/303583.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:42:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303583.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303583.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303583.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303583.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303583.html</trackback:ping><description><![CDATA[<p>学习动态性能表第17篇-(1)-V$SEGSTAT</p>
<p>本视图实时监控段级(segment-level)统计项，支持oracle9ir2及更高版本</p>
<p><strong>V$SEGSTAT中的常用列</strong><br />
TS#：表空间标识<br />
OBJ#：字典对象标识<br />
DATAOBJ#：数据对象标识<br />
STATISTIC_NAME：统计项名称<br />
STATISTIC#：统计项标识<br />
VALUE：统计项值</p>
<p><strong>V$SEGSTAT中的连接列</strong><br />
Column View Joined Column(s) <br />
-------------- ----------------------- ------------------------<br />
TS# V$TABLESPACE TS#<br />
OBJ# ALL_OBJECTS OBJECT_ID</p>
<p><strong>示例：</strong><br />
查询指定对象的统计<br />
select * from v$segstat where ts# = 11<br />
and obj# = (select object_id from user_objects<br />
where object_name = 'TMPTABLE1' and owner = 'JSS')</p>
<p>
<p>第17篇-(2)-V$SEGMENT_STATISTICS</p>
<p>　　这是一个友好的视图，支持Oracle9ir2及更高版本。实时监测段级(segment-level)统计项，可用于鉴定性能问题源于表或索引</p>
<p><strong>V$SEGMENT_STATISTICS中的列</strong><br />
OWNER：对象所有者<br />
OBJECT_NAME：对象名称<br />
SUBOBJECT_NAME：子对象名称<br />
TABLESPACE_NAME：对象所在表空间<br />
TS#：表空间标识<br />
OBJ#：字典对象标识<br />
DATAOBJ#：数据对象标识<br />
OBJECT_TYPE：对象类型<br />
STATISTIC_NAME：统计项名称<br />
STATISTIC#：统计项标识<br />
VALUE：统计项值</p>
<p><br />
基本与上相同，只是信息更加详细，不再赘述。</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303583.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:42 <a href="http://www.blogjava.net/javaex/articles/303583.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(16)--V$ROWCACHE 转自 http://junsansi.itpub.net/post/29894/294600</title><link>http://www.blogjava.net/javaex/articles/303582.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:41:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303582.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303582.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303582.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303582.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303582.html</trackback:ping><description><![CDATA[<p>学习动态性能表第16篇--V$ROWCACHE</p>
<p>　　本视图显示数据字典缓存(也叫rowcache)的各项统计。每一条记录包含不同类型的数据字典缓存数据统计，注意数据字典缓存有层次差别，因此同样的缓存名称可能不止一次出现。</p>
<p><strong>V$ROWCACHE常用列</strong><br />
PARAMETER：缓存名<br />
COUNT：缓存项总数<br />
USAGE：包含有效数据的缓存项数<br />
GETS：请求总数<br />
GETMISSES：请求失败数<br />
SCANS：扫描请求数<br />
SCANMISSES：扫描请求失败次数<br />
MODIFICATIONS：添加、修改、删除操作数<br />
DLM_REQUESTS：DLM请求数<br />
DLM_CONFLICTS：DLM冲突数<br />
DLM_RELEASES：DLM释放数<br />
<br />
<strong>使用V$ROWCACHE数据</strong></p>
<p>1&gt;.确认数据字典缓存是否拥有适当的大小。如果shared pool过小，那数据字典缓存就不足以拥有合适的大小以缓存请求信息。<br />
2&gt;.确认应用是否有效访问缓存。如果应用设计未能有效使用数据字典缓存(比如，大数据字典缓存并不有助于解决性能问题)。例如，DC_USERS缓存在过去某段时期内出现大量GETS，看起来像是数据库中创建了大量的不同用户，并且应用记录下用户频繁登陆和注销。通过检查logon比率以及系统用户数可以验证上述数据。同时解析比率也会很高，如果这是一个大型的OLTP系统的中间层，它可能在中间层更有效的管理个别帐户，允许中间层以单用户登陆成为应用所有者。通过保持活动连接来减少logon/logoff比率也同样有效。<br />
3&gt;.确认是否发生动态空间分配。DC_SEGMENTS, DC_USED_EXTENTS, 以及DC_FREE_EXTENTS大量的类似大小修改将指出存在大量动态空间分配。可行的解决方案包括指定下一个区大小或者使用本地管理表空间。如果发生空间分配的是临时的表空间，则可以为其指定真正的临时表空间(If the space allocation is occurring on the temp tablespace, then use a true temporary tablespace for the temp. )。<br />
4&gt;.dc_sequences值的变化指出是否大量sequence号正在产生。<br />
5&gt;.搜集硬解析的证据。硬解析常表现为大量向DC_COLUMNS, DC_VIEWS 以及 DC_OBJECTS caches的gets。</p>
<p><br />
<strong>示例：</strong><br />
1.分组统计数据字典统计项<br />
SELECT parameter,sum("COUNT"),sum(usage),sum(gets),sum(getmisses),<br />
sum(scans),sum(scanmisses),sum(modifications),<br />
sum(dlm_requests),sum(dlm_conflicts),sum(dlm_releases)<br />
FROM V$ROWCACHE<br />
GROUP BY parameter;</p>
<p>2.检查数据字典的命中率<br />
select 1 - sum(getmisses) / sum(gets) "data dictionary hitratio" from v$rowcache;</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303582.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:41 <a href="http://www.blogjava.net/javaex/articles/303582.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(15)--V$ROLLSTAT 转自 http://junsansi.itpub.net/post/29894/294598</title><link>http://www.blogjava.net/javaex/articles/303581.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:40:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303581.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303581.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303581.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303581.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303581.html</trackback:ping><description><![CDATA[<p>学习动态性能表第15篇--V$ROLLSTAT</p>
<p>本视图自启动即保持并记录各回滚段统计项。</p>
<p><strong>V$ROLLSTAT中的常用列</strong><br />
USN：回滚段标识<br />
RSSIZE：回滚段默认大小<br />
XACTS：活动事务数</p>
<p><strong>在一段时间内增量用到的列</strong><br />
WRITES：回滚段写入数(单位:bytes)<br />
SHRINKS：回滚段收缩次数<br />
EXTENDS：回滚段扩展次数<br />
WRAPS：回滚段翻转(wrap)次数<br />
GETS：获取回滚段头次数<br />
WAITS：回滚段头等待次数</p>
<p><strong>V$ROLLSTAT中的连接列</strong><br />
Column View Joined Column(s) <br />
-------------- ----------------------- ------------------------<br />
USN V$ROLLNAME USN</p>
<p><strong>注意：</strong><br />
　　通过花费时间除以翻转次数，你可以得到一次回滚段翻转(wrap)的平均用时。此方法常用于在长查询中指定合适的回滚段大小以避免'Snapshot Too Old'错误。同时，通过查看extends和shrinks列可以看出optimal是否需要增加。</p>
<p><strong>示例：</strong><br />
1.查询回滚段的信息。所用数据字典：DBA_ROLLBACK_SEGS，可以查询的信息：回滚段的标识(SEGMENT_ID)、名称(SEGMENT_NAME)、所在表空间(TABLESPACE_NAME)、类型(OWNER)、状态(STATUS)。 <br />
select * from DBA_ROLLBACK_SEGS </p>
<p>查看回滚段的统计信息：<br />
SELECT n.name, s.extents, s.rssize, s.optsize, s.hwmsize, s.xacts, s.status<br />
FROM v$rollname n, v$rollstat s<br />
WHERE n.usn = s.usn;</p>
<p>3.查看回滚段的使用情况，哪个用户正在使用回滚段的资源:<br />
select s.username, u.name<br />
from v$transaction t, v$rollstat r, v$rollname u, v$session s<br />
where s.taddr = t.addr<br />
and t.xidusn = r.usn<br />
and r.usn = u.usn<br />
order by s.username;</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303581.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:40 <a href="http://www.blogjava.net/javaex/articles/303581.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(14)--V$PARAMETER&amp;V$SYSTEM_PARAMETER 转自三思 http://junsansi.itpub.net/post/29894/294595</title><link>http://www.blogjava.net/javaex/articles/303580.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:39:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303580.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303580.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303580.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303580.html</trackback:ping><description><![CDATA[<p>学习动态性能表第14篇--V$PARAMETER&amp;V$SYSTEM_PARAMETER</p>
<p><br />
　　这两个视图列出的各参数项名称以及参数值。V$PARAMETER显示执行查询的session的参数值。V$SYSTEM_PARAMETER视图则列出实例的参数值。</p>
<p>例如，下列查询显示执行查询的session的SORT_AREA_SIZE参数值：<br />
SELECT value<br />
FROM V$PARAMETER<br />
WHERE name = 'sort_area_size';<br />
呵呵，可能有朋友还是不明白v$parameter和v$system_parameter的区别，我再举个例子，相信你马上就明白了。<br />
SQL&gt;select value from v$parameter where name = 'global_names';</p>
<p>VALUE<br />
------------------------------------------------------------------------------------------------<br />
TRUE</p>
<p>1 row selected.</p>
<p>SQL&gt; alter session set global_names = false;</p>
<p>Session altered.</p>
<p>SQL&gt; select value from v$parameter where name = 'global_names';</p>
<p>VALUE<br />
------------------------------------------------------------------------------------------------<br />
FALSE</p>
<p>1 row selected.</p>
<p>SQL&gt; select value from v$system_parameter where name = 'global_names';</p>
<p>VALUE<br />
------------------------------------------------------------------------------------------------<br />
TRUE</p>
<p>1 row selected.</p>
<p><br />
<strong>V$PARAMETER中的常用列：</strong><br />
NAME：参名<br />
VALUE：参值(session或实例)<br />
ISDEFAULT：参值是否默认值<br />
ISSES_MODIFIABLE：此参数是否session级可修改<br />
ISSYS_MODIFIABLE：此参数在实例启动后是否可由实例修改<br />
ISMODIFIED：自实例启动起，参值是否被修改，如果被修改，session级或是实例(系统)级修改(如果执行一条alter session,则值将被MODIFIED，如果执行的是alter system，则值为SYS_MODIFIED)<br />
ISADJUSTED：<br />
DESCRIPTION：参数简要描述<br />
UPDATE_COMMENT：由dba提供的参数说明</p>
<p><strong>使用v$parameter以及v$system_parameter数据：</strong></p>
<p>　　在调优期间通过查询v$parameter以确认当前参数设置。例如，如果buffer cache hit ratio较低，那么通过查询DB_BLOCK_BUFFERS(或DB_CACHE_SIZE)可以明确当前的buffer cache大小。</p>
<p>SELECT name, value, isdefault, isses_modifiable, issys_modifiable, ismodified<br />
FROM V$PARAMETER<br />
WHERE name = 'sort_area_size';</p>
<p>NAME VALUE ISDEF ISSES ISSYS_MOD ISMODIFIED<br />
-------------------- ---------- ----- ----- --------- ----------<br />
sort_area_size 1048576 TRUE TRUE DEFERRED MODIFIED</p>
<p><br />
前例显示了SORT_AREA_SIZE初始参数在实例启动时并非初始值，不过被session修改回了初始值。<br />
注意：当查询v$parameter时要注意，如果你想查看实例参数，要查询v$system_parameter。</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:39 <a href="http://www.blogjava.net/javaex/articles/303580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(13)--V$OPEN_CURSOR 转自三思 http://junsansi.itpub.net/post/29894/294344</title><link>http://www.blogjava.net/javaex/articles/303579.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:38:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303579.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303579.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303579.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303579.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303579.html</trackback:ping><description><![CDATA[<p>学习动态性能表第13篇--V$OPEN_CURSOR</p>
<p>　　本视图列出session打开的所有cursors，很多时候都将被用到，比如：你可以通过它查看各个session打开的cursor数。</p>
<p>　　当诊断系统资源占用时，它常被用于联接v$sqlarea和v$sql查询出特定SQL(高逻辑或物理I/O)。然后，下一步就是找出源头。在应用环境，基本都是同一类用户登陆到数据库(在V$SQLAREA中拥有相同的PARSING_USER_ID)，而通过这个就可以找出它们的不同。V$SQLAREA中的统计项在语句完全执行后被更新(并且从V$SESSION.SQL_HASH_VALUE中消失)。因此，你不能直接找到session除非语句被再次执行。不过如果session的cursor仍然打开着，你可以通过v$open_cursor找出执行这个语句的session。</p>
<p><strong>V$OPEN_CURSOR中的连接列</strong></p>
<p>Column View Joined Column(s) <br />
----------------------------- ---------------------------------------- -----------------------------<br />
HASH_VALUE, ADDRESS V$SQLAREA, V$SQL, V$SQLTEXT HASH_VALUE, ADDRESS<br />
SID V$SESSION SID</p>
<p><strong>示例：</strong><br />
1.找出执行某语句的session：<br />
SELECT hash_value, buffer_gets, disk_reads <br />
FROM V$SQLAREA<br />
WHERE disk_reads &gt; 1000000 <br />
ORDER BY buffer_gets DESC;</p>
<p>HASH_VALUE BUFFER_GETS DISK_READS<br />
---------- ----------- ----------<br />
1514306888 177649108 3897402<br />
478652562 63168944 2532721<br />
360282550 14158750 2482065</p>
<p>3 rows selected.<br />
SQL&gt; SELECT sid FROM V$SESSION WHERE sql_hash_value = 1514306888 ;<br />
no rows selected<br />
--直接通过hash_value查找v$session，没有记录</p>
<p>SQL&gt; SELECT sid FROM V$OPEN_CURSOR WHERE hash_Value = 1514306888 ;</p>
<p>SID<br />
-----<br />
1125<br />
233<br />
935<br />
1693<br />
531</p>
<p>5 rows selected.<br />
--通过hash_value在v$open_cursor中查找sid(只有在session的cursor仍然打开的情况下才有可能找到)</p>
<p>2.列出拥有超过400个cursor的sessionID<br />
SQL&gt; SELECT sid, count(0) ct FROM v$open_cursor <br />
GROUP BY sid HAVING COUNT(0) &gt; 400 ORDER BY ct desc;</p>
<p>事实上，v$open_cursor是一个相当常用的视图，特别是web开发应用的时候。仅通过它一个视图你就能分析出当前的连接情况，主要执行语句等。</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:38 <a href="http://www.blogjava.net/javaex/articles/303579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(12)--V$DB_OBJECT_CACHE 转自三思 http://junsansi.itpub.net/post/29894/294343</title><link>http://www.blogjava.net/javaex/articles/303578.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:37:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303578.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303578.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303578.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303578.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303578.html</trackback:ping><description><![CDATA[<p>学习动态性能表第12篇--V$DB_OBJECT_CACHE </p>
<p>　　本视图提供对象在library cache(shared pool)中对象统计，提供比v$librarycache更多的细节，并且常用于找出shared pool中的活动对象。</p>
<p><strong>v$db_object_cache中的常用列：</strong>OWNER：对象拥有者<br />
NAME：对象名称<br />
TYPE：对象类型(如，sequence,procedure,function,package,package body,trigger)<br />
KEPT：告知是否对象常驻shared pool(yes/no)，有赖于这个对象是否已经利用PL/SQL 过程DBMS_SHARED_POOL.KEEP&#8220;保持&#8221;（永久固定在内存中）<br />
SHARABLE_MEM：共享内存占用<br />
PINS：当前执行对象的session数<br />
LOCKS：当前锁定对象的session数</p>
<p><strong>瞬间状态列：</strong><br />
下列列保持对象自初次加载起的统计信息：<br />
LOADS：对象被加载次数。</p>
<p><strong>示例：</strong><br />
1.shared pool执行以及内存使用总计<br />
下列查询显示出shared pool内存对不同类别的对象<br />
同时也显示是否有对象通过DBMS_SHARED_POOL.KEEP()过程常驻shared pool。<br />
SELECT type, kept, COUNT(*), SUM(sharable_mem)<br />
FROM V$DB_OBJECT_CACHE<br />
GROUP BY type, kept;</p>
<p>2.通过载入次数找出对象<br />
SELECT owner, name sharable_mem, kept, loads<br />
FROM V$DB_OBJECT_CACHE<br />
WHERE loads &gt; 1 ORDER BY loads DESC;</p>
<p>找出使用的内存超过10M并且不在常驻内存的对象。<br />
SELECT owner, name, sharable_mem, kept<br />
FROM V$DB_OBJECT_CACHE<br />
WHERE sharable_mem &gt; 102400 AND kept = 'NO'<br />
ORDER BY sharable_mem DESC;</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:37 <a href="http://www.blogjava.net/javaex/articles/303578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(11)--v$latch$v$latch_children </title><link>http://www.blogjava.net/javaex/articles/303577.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:35:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303577.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303577.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303577.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303577.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303577.html</trackback:ping><description><![CDATA[<p>学习动态性能表第十一篇-(1)-V$LATCH</p>
<p>　　Oracle Rdbms应用了各种不同类型的锁定机制，latch即是其中的一种。Latch是用于保护SGA区中共享数据结构的一种串行化锁定机制。Latch的实现是与操作系统相关的，尤其和一个进程是否需要等待一个latch、需要等待多长时间有关。Latch是一种能够极快地被获取和释放的锁，它通常用于保护描述buffer cache中block的数据结构。与每个latch相联系的还有一个清除过程，当持有latch的进程成为死进程时，该清除过程就会被调用。Latch还具有相关级别，用于防止死锁，一旦一个进程在某个级别上得到一个latch，它就不可能再获得等同或低于该级别的latch。 </p>
<p>　　本视图保存自实例启动各类栓锁的统计信息。常用于当v$session_wait中发现栓锁竞争时鉴别SGA区中问题所在区域。</p>
<p>　　v$latch表的每一行包括了对不同类型latch的统计，每一列反映了不同类型的latch请求的活动情况。不同类型的latch请求之间的区别在于，当latch不可立即获得时，请求进程是否继续进行。按此分类，latch请求的类型可分为两类：willing-to-wait和immediate。</p>
<p>　　Willing-to-wait：是指如果所请求的latch不能立即得到，请求进程将等待一很短的时间后再次发出请求。进程一直重复此过程直到得到latch。 <br />
　　Immediate：是指如果所请求的latch不能立即得到，请求进程就不再等待，而是继续执行下去。 </p>
<p><strong>V$LATCH中的常用列：</strong><br />
NAME：latch名称<br />
IMMEDIATE_GETS：以Immediate模式latch请求数<br />
IMMEDIATE_MISSES：请求失败数<br />
GETS：以Willing to wait请求模式latch的请求数<br />
MISSES：初次尝试请求不成功次数<br />
SPIN_GETS：第一次尝试失败，但在以后的轮次中成功<br />
SLEEP[x]：成功获取前sleeping次数<br />
WAIT_TIME：花费在等待latch的时间</p>
<p><strong>V$LATCH中的连接列</strong><br />
Column View Joined Column(s) <br />
--------------------- ------------------------------ ------------------------<br />
NAME/LATCH# V$LATCH_CHILDREN NAME/LATCH#<br />
NAME V$LATCHHOLDER NAME<br />
NAME/LATCH# V$LATCHNAME NAME/LATCH# <br />
NAME V$LATCH_MISSES PARENT_NAME</p>
<p><strong>示例：</strong>下列的示例中，创建一个表存储查询自v$latch的数据：<br />
CREATE TABLE snap_latch as SELECT 0 snap_id, sysdate snap_date, a.* FROM V$LATCH a; <br />
ALTER TABLE snap_latch add (constraint snap_filestat primary key (snap_id, name)); </p>
<p>最初，snap_id被置为0，稍后，snap_latch表的snap_id列被更新为1：<br />
INSERT INTO snap_latch SELECT 1, sysdate, a.* FROM V$LATCH a; <br />
注意你通过sql语句插入记录时必须增加snap_id的值。</p>
<p>在你连续插入记录之后，使用下列的select语句列出统计。注意0不能成为被除数。</p>
<p>SELECT SUBSTR(a.name,1,20) NAME, (a.gets-b.gets)/1000 "Gets(K)",<br />
(a.gets-b.gets)/(86400*(a.snap_date-b.snap_date)) "Get/s",<br />
DECODE ((a.gets-b.gets), 0, 0, (100*(a.misses-b.misses)/(a.gets-b.gets))) MISS,<br />
DECODE ((a.misses-b.misses), 0, 0,<br />
(100*(a.spin_gets-b.spin_gets)/(a.misses-b.misses))) SPIN,<br />
(a.immediate_gets-b.immediate_gets)/1000 "Iget(K)",<br />
(a.immediate_gets-b.immediate_gets)/ (86400*(a.snap_date-b.snap_date)) "IGet/s",<br />
DECODE ((a.immediate_gets-b.immediate_gets), 0, 0,<br />
(100*(a.immediate_misses-b.immediate_misses)/ (a.immediate_gets-b.immediate_gets))) </p>
<p>IMISS<br />
FROM snap_latch a, snap_latch b<br />
WHERE a.name = b.name<br />
AND a.snap_id = b.snap_id + 1<br />
AND ( (a.misses-b.misses) &gt; 0.001*(a.gets-b.gets)<br />
or (a.immediate_misses-b.immediate_misses) &gt; <br />
0.001*(a.immediate_gets-b.immediate_gets))<br />
ORDER BY 2 DESC;</p>
<p>下例列出latch统计项，miss列小于0.1%的记录已经被过滤。<br />
NAME Gets(K) Get/s MISS SPIN IGets(K) IGet/s IMISS<br />
------------------ -------- ------- ----- ------ -------- ------- -----<br />
cache buffers chai 255,272 69,938 0.4 99.9 3,902 1,069 0.0<br />
library cache 229,405 62,851 9.1 96.9 51,653 14,151 3.7<br />
shared pool 24,206 6,632 14.1 72.1 0 0 0.0<br />
latch wait list 1,828 501 0.4 99.9 1,836 503 0.5<br />
row cache objects 1,703 467 0.7 98.9 1,509 413 0.2<br />
redo allocation 984 270 0.2 99.7 0 0 0.0<br />
messages 116 32 0.2 100.0 0 0 0.0<br />
cache buffers lru 91 25 0.3 99.0 7,214 1,976 0.3<br />
modify parameter v 2 0 0.1 100.0 0 0 0.0<br />
redo copy 0 0 92.3 99.3 1,460 400 0.0</p>
<p>什么时候需要检查latch统计呢？看下列项：</p>
<p>misses/gets的比率是多少<br />
获自spinning的misses的百分比是多少<br />
latch请求了多少次<br />
latch休眠了多少次</p>
<p>　　Redo copy latch看起来有很高的的失误率，高达92.3%。不过，我们再仔细看的话，Redo copy latches是获自immediate模式。immediate模式的数值看起来还不错，并且immediate模式只有个别数大于willing to wait模式。所以Redo copy latch其实并不存在竞争。不过，看起来shared pool和library cache latches可能存在竞争。考虑执行一条查询检查latches的sleeps以确认是否确实存在问题。</p>
<p>latch有40余种，但作为DBA关心的主要应有以下几种： <br />
Cache buffers chains latch：当用户进程搜索SGA寻找database cache buffers时需要使用此latch。<br />
Cache buffers LRU chain latch：当用户进程要搜索buffer cache中包括所有 dirty blocks的LRU (least recently used) 链时使用该种latch。 <br />
Redo log buffer latch：这种latch控制redo log buffer中每条redo entries的空间分配。 <br />
Row cache objects latch：当用户进程访问缓存的数据字典数值时，将使用Row cache objects latch。 </p>
<p><strong>Latches调优</strong></p>
<p>不要调整latches。如果你发现latch存在竞争，它可能是部分SGA资源使用反常的征兆。要修正问题所在，你更多的是去检查那部分SGA资源使用的竞争情况。仅仅从v$latch是无法定位问题所在的。</p>
<p>关于latches的更多信息可以浏览Oracle Database Concepts。</p>
<p>第十一篇-(2)-V$LATCH_CHILDREN</p>
<p>　　数据库中有些类别的latches拥有多个。V$LATCH中提供了每个类别的总计信息。如果想看到单个latch，你可以通过查询本视图。</p>
<p>例如：<br />
select name,count(*) ct from v$Latch_children group by name order by ct desc;</p>
<p>与v$latch相比，除多child#列外，其余列与之同，不详述~~</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303577.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:35 <a href="http://www.blogjava.net/javaex/articles/303577.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(十)--V$SESSION_LONGOPS 转自三思 http://junsansi.itpub.net/post/29894/293212</title><link>http://www.blogjava.net/javaex/articles/303576.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:34:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303576.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303576.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303576.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303576.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303576.html</trackback:ping><description><![CDATA[<p>学习动态性能表第十篇--V$SESSION_LONGOPS</p>
<p>本视图显示运行超过6秒的操作的状态。包括备份，恢复，统计信息收集，查询等等。</p>
<p>要监控查询执行进展状况，你必须使用cost-based优化方式，并且：<br />
设置TIMED_STATISTICS或SQL_TRACE参数值为true。<br />
通过ANALYZE或DBMS_STATS数据包收集对象统计信息。</p>
<p>你可以通过DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS过程添加application-specific长运行操作信息到本视图。关于DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS的更多信息可以浏览：Oracle Supplied PL/SQL Packages and Types Reference。</p>
<p><strong>V$SESSION_LONGOPS列说明</strong></p>
<p>SID：Session标识<br />
SERIAL#：Session串号<br />
OPNAME：操作简要说明<br />
TARGET：操作运行所在的对象<br />
TARGET_DESC：目标对象说明<br />
SOFAR：至今为止完成的工作量<br />
TOTALWORK：总工作量<br />
UNITS：工作量单位<br />
START_TIME：操作开始时间<br />
LAST_UPDATE_TIME：统计项最后更新时间<br />
TIME_REMAINING：预计完成操作的剩余时间(秒)<br />
ELAPSED_SECONDS：从操作开始总花费时间(秒)<br />
CONTEXT：前后关系<br />
MESSAGE：统计项的完整描述<br />
USERNAME：执行操作的用户ID<br />
SQL_ADDRESS：用于连接查询的列<br />
SQL_HASH_VALUE：用于连接查询的列<br />
QCSID：</p>
<p><strong>示例：</strong><br />
找一较大表，确认该表查询将超过6秒，哎呀让它快咱没把握，让它慢这可是我的强项啊~~<br />
SQL&gt; set timing on<br />
SQL&gt; create table ttt as select level lv,rownum rn from dual connect by level&lt;10000000; --创建一个临时表<br />
Table created<br />
Executed in 19.5 seconds<br />
SQL&gt; commit;<br />
Commit complete<br />
Executed in 0 seconds<br />
SQL&gt; select * from (select * from ttt order by lv desc) where rownum&lt;2; --执行一个费时的查询<br />
<br />
LV RN<br />
---------- ----------<br />
9999999 9999999<br />
Executed in 9.766 seconds --哈哈，成功超过6秒<br />
SQL&gt; select sid,opname,sofar,totalwork,units,sql_hash_value from v$session_longops; ----看看v$session_longops中是不是已经有记录了<br />
<br />
SID OPNAME SOFAR TOTALWORK UNITS SQL_HASH_VALUE<br />
---------- ---------------------------------------------------------------- ---------- ---------- -------------------------------- --------------<br />
10 Table Scan 47276 47276 Blocks 2583310173<br />
Executed in 0.047 seconds<br />
<br />
SQL&gt; select a.sql_text from v$sqlarea a,v$session_longops b where a.HASH_VALUE=b.SQL_HASH_VALUE; --通过hash_value联系查询出刚执行的查询语句。<br />
<br />
SQL_TEXT<br />
--------------------------------------------------------------------------------<br />
select * from (select * from ttt order by lv desc) where rownum&lt;2<br />
Executed in 0.063 seconds</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:34 <a href="http://www.blogjava.net/javaex/articles/303576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(九)--V$FILESTAT 转自三思 http://junsansi.itpub.net/post/29894/293209</title><link>http://www.blogjava.net/javaex/articles/303574.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303574.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303574.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303574.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303574.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303574.html</trackback:ping><description><![CDATA[<p>学习动态性能表第九篇--V$FILESTAT</p>
<p>　　本视图记录各文件物理I/O信息。如果瓶颈与I/O相关，可用于分析发生的活动I/O事件。V$FILESTAT显示出数据库I/O的下列信息(不包括日志文件)：</p>
<p>物理读写数<br />
块读写数<br />
I/O读写总耗时</p>
<p>　　以上数值自实例启动即开始记录。如果获取了两个快照，那么二者之间的差异即是这一时间段内活动I/O统计。</p>
<p><strong>V$FILESTAT中的常用列：</strong></p>
<p>FILE#：文件序号；<br />
PHYRDS：已完成的物理读次数；<br />
PHYBLKRD：块读取数；<br />
PHYWRTS：DBWR完成的物理写次数；<br />
PHYBLKWRT：写入磁盘的块数；</p>
<p><strong>V$FILESTAT注意项：</strong></p>
<p>因为multiblock读调用，物理读数和数据块读数有可能不同；<br />
因为进程直写，物理写和数据块写也可能不一致；<br />
Sum(physical blocks read) 近似于v$sysstat中的physical reads；<br />
Sum(physical blocks written) 近似于v$sysstat中的physical writes；<br />
数据读(由缓存读比直读好)由服务进程处理。从buffer cache写只能由DBWR进行，直写由服务进程处理。</p>
<p><strong>V$FILESTAT中的连接列</strong><br />
Column View Joined Column(s) <br />
----------- ------------------------- -------------------------<br />
FILE# DBA_DATA_FILES FILE_ID<br />
FILE# V$DATAFILE FILE#</p>
<p><strong>示例：</strong><br />
获得数据文件物理读写和数据块读写信息：<br />
select df.tablespace_name name,<br />
df.file_name "file",<br />
f.phyrds pyr,<br />
f.phyblkrd pbr,<br />
f.phywrts pyw,<br />
f.phyblkwrt pbw<br />
from v$filestat f, dba_data_files df where f.file# = df.file_id<br />
order by df.tablespace_name;<br />
注意：尽管oracle记录的读写次数非常精确，但如果数据库运行在Unix文件系统(UFS)有可能不能表现真实的磁盘读写，例如，读次数可能并非真实的磁盘读，而是UFS缓存。不过裸设备的读写次数应该是比较精准的。</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303574.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:33 <a href="http://www.blogjava.net/javaex/articles/303574.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(八)-(3)-V$LOCKED_OBJECT 转自三思 http://junsansi.itpub.net/post/29894/292825</title><link>http://www.blogjava.net/javaex/articles/303573.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303573.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303573.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303573.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303573.html</trackback:ping><description><![CDATA[<p>学习动态性能表第八篇-(2)-V$LOCKED_OBJECT</p>
<p>　　本视图列出系统上的每个事务处理所获得的所有锁。</p>
<p><strong>V$LOCKED_OBJECT中的列说明：</strong></p>
<p>XIDUSN：回滚段号<br />
XIDSLOT：槽号<br />
XIDSQN：序列号<br />
OBJECT_ID：被锁对象ID<br />
SESSION_ID：持有锁的sessionID<br />
ORACLE_USERNAME：持有锁的Oracle 用户名<br />
OS_USER_NAME：持有锁的操作系统 用户名<br />
PROCESS：操作系统进程号<br />
LOCKED_MODE：锁模式，值同上表1</p>
<p><strong>示例：</strong>1.以DBA角色, 查看当前数据库里锁的情况可以用如下SQL语句：<br />
select object_id,session_id,locked_mode from v$locked_object;</p>
<p>select t2.username, t2.sid, t2.serial#, t2.logon_time<br />
from v$locked_object t1, v$session t2<br />
where t1.session_id = t2.sid order by t2.logon_time;</p>
<p>如果有长期出现的一列，可能是没有释放的锁。我们可以用下面SQL语句杀掉长期没有释放非正常的锁：</p>
<p>alter system kill session 'sid,serial#';</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:26 <a href="http://www.blogjava.net/javaex/articles/303573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(八)-(2)-v$lock 转自三思 http://junsansi.itpub.net/post/29894/292819</title><link>http://www.blogjava.net/javaex/articles/303571.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:25:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303571.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303571.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303571.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303571.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303571.html</trackback:ping><description><![CDATA[<p><strong>V$LOCK中的连接列</strong></p>
<p>Column View Joined Column(s) <br />
SID V$SESSION SID<br />
ID1, ID2, TYPE V$LOCK ID1, ID2, TYPE<br />
ID1 DBA_OBJECTS OBJECT_ID<br />
TRUNCID1/65536) V$ROLLNAME USN</p>
<p>如果session在等待锁，这可被用于找出session持有的锁，。<br />
可被用于找出DML锁类型的被锁对象(type='TM')<br />
可被用于找出行级事务锁(TYPE='TX')使用中的回滚段，不过，需要通过V$TRANSACTION连接查询得到。</p>
<p>表1 Oracle的TM锁类型 <br />
锁模式 锁描述 解释 SQL操作 <br />
0 none <br />
1 NULL 空 Select <br />
2 SS(Row-S) 行级共享锁，其他对象只能查询这些数据行 Select for update、Lock for update、Lock row share <br />
3 SX(Row-X) 行级排它锁，在提交前不允许做DML操作 Insert、Update、Delete、Lock row share <br />
4 S(Share) 共享锁 Create index、Lock share <br />
5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive <br />
6 X(Exclusive) 排它锁 Alter table、Drop able、Drop index、Truncate table 、Lock exclusive </p>
<p>　　数字越大锁级别越高, 影响的操作越多。一般的查询语句如select ... from ... ;是小于2的锁, 有时会在v$locked_object出现。select ... from ... for update; 是2的锁。</p>
<p>　　当对话使用for update子串打开一个游标时，所有返回集中的数据行都将处于行级(Row-X)独占式锁定，其他对象只能查询这些数据行，不能进行update、delete或select...for update操作。insert / update / delete ... ; 是3的锁。 </p>
<p>　　没有commit之前插入同样的一条记录会没有反应, 因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作。</p>
<p>　　创建索引的时候也会产生3,4级别的锁。locked_mode为2,3,4不影响DML(insert,delete,update,select)操作, 但DDL(alter,drop等)操作会提示ora-00054错误。有主外键约束时 update / delete ... ; 可能会产生4,5的锁。DDL语句时是6的锁。</p>
<p>　　如果出现了锁的问题, 某个DML操作可能等待很久没有反应。当你采用的是直接连接数据库的方式，也不要用OS系统命令 $kill process_num 或者 $kill -9 process_num来终止用户连接，因为一个用户进程可能产生一个以上的锁, 杀OS进程并不能彻底清除锁的问题。记得在数据库级别用alter system kill session 'sid,serial#';杀掉不正常的锁。</p>
<p><strong>示例：</strong><br />
我按照自己的理解演示的TX,TM锁如下：<br />
1.create table TMP1(col1 VARCHAR2(50));--创建临时表<br />
2.select * from v$lock;--关掉当前锁信息<br />
3.select * from tmp1 for update; --加锁<br />
4.select * from v$lock; ---看看现在的锁列表，是不是多了两条记录。Type分别为tx,tm，对照表1。<br />
5.新开一个连接，然后<br />
select * from tmp1 for update; --呵呵，等待状态了吧<br />
6.select * from v$lock; --又新增了两条记录，其它一条type=tx,lmode=0<br />
7.查看当前被锁的session正在执行的sql语句<br />
select /*+ NO_MERGE(a) NO_MERGE(b) NO_MERGE(c) */ a.username, a.machine, a.sid, a.serial#, a.last_call_et "Seconds", b.id1, c.sql_text "SQL"<br />
from v$session a, v$lock b, v$sqltext c<br />
where a.username is not null and a.lockwait = b.kaddr and c.hash_value =a.sql_hash_value<br />
8.将之前的for update语句commit或者rollback，然后新开连接的session拥有锁。有兴趣的朋友还可以试试两条for update的时候，关闭先执行的那个窗口，看看oracle会给出什么样的响应。</p>
<p>　　这一节是我在自整理v$系列视图以来花费时间和精力最多的一个，我反复看了document，又从网上搜索了各种资料实际使用案例等，就是不开窍。这一节至今我也仍未有把握说尽在掌握，所以在上述文字中除了例子，我如实贴出了收集来的内容，未加任何自我理解，就是担心万一我的理解有误，会对其它浏览本文的人造成困扰。同时我把在收集过程中自我感觉对理解v$lock可能有帮助的资料地址列出，供有心人参考：</p>
<p>Oracle数据库中的锁机制研究<br />
<a href="http://soft.zdnet.com.cn/software_zone/2007/0208/377403.shtml">http://soft.zdnet.com.cn/software_zone/2007/0208/377403.shtml</a></p>
<p>DB2和 Oracle的并发控制（锁）比较<br />
<a href="http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0512niuxzh/">http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0512niuxzh/</a></p>
<p>Itpub论坛的oracle专题深入讨论区也有一篇非常精彩的讨论，地址如下：<br />
我对ORACLE数据锁的一点体会<br />
<a href="http://www.itpub.net/270059.html">http://www.itpub.net/270059.html</a></p>
<img src ="http://www.blogjava.net/javaex/aggbug/303571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:25 <a href="http://www.blogjava.net/javaex/articles/303571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(八)-(1)-v$lock 转自三思 http://junsansi.itpub.net/post/29894/292816</title><link>http://www.blogjava.net/javaex/articles/303570.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:23:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303570.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303570.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303570.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303570.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303570.html</trackback:ping><description><![CDATA[<p>学习动态性能表第八篇-(1)-V$LOCK</p>
<p>　　本视图列出Oracle 服务器当前拥有的锁以及未完成的锁或栓锁请求。如果你觉着session在等待等待事件队列那你应该检查本视图。如果你发现session在等待一个锁。那么按如下先后顺序：<br />
1.使用V$LOCK找出session持有的锁。<br />
2.使用V$SESSION找出持有锁或等待锁的session执行的sql语句。<br />
3.使用V$SESSION_WAIT找出什么原因导致session持有锁堵塞。<br />
4.使用V$SESSION获取关于持有锁的程序和用户的更多信息。</p>
<p><strong>V$LOCK中的常用列</strong><br />
&#183;SID：表示持有锁的会话信息。<br />
&#183;TYPE：表示锁的类型。值包括TM和TX等。<br />
&#183;LMODE：表示会话等待的锁模式的信息。用数字0－6表示，和表1相对应。<br />
&#183;REQUEST：表示session请求的锁模式的信息。<br />
&#183;ID1,ID2：表示锁的对象标识。</p>
<p><strong>公共锁类型</strong></p>
<p>　　在Oracle数据库中，DML锁主要包括TM锁和TX锁，其中TM锁称为表级锁，TX锁称为事务锁或行级锁。</p>
<p>　　当Oracle执行DML语句时，系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后，系统再自动申请TX类型的锁，并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志，而只需检查TM锁模式的相容性即可，大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式，在数据库中用0－6来表示。不同的SQL操作产生不同类型的TM锁，如下表1。</p>
<p><strong>TX：行级锁，事务锁</strong><br />
&#183;在改变数据时必须是排它模式(mode 6)。<br />
&#183;每一个活动事务都拥有一个锁。它将在事务结束(commit/rollback)时释放。<br />
&#183;如果一个块包括的列被改变而没有ITL(interested transaction list)槽位(entries)，那么session将锁置于共享模式(mode 4)。当session获得块的ITL槽位时释放。<br />
&#183;当一个事务首次发起一个DML语句时就获得一个TX锁，该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行DML语句时，第一个会话在该条记录上加锁，其他的会话处于等待状态。当第一个会话提交后，TX锁被释放，其他会话才可以加锁。<br />
&#183;指出回滚段和事务表项</p>
<p>　按下列项以避免竞争：<br />
　　&#183;避免TX－6类型竞争，需要根据您的应用而定。<br />
　　&#183;避免TX－4类型竞争，可以考虑增加对象INITRANS参数值。</p>
<p><strong>TM：表级锁</strong></p>
<p>&#183;数据库执行任何DDL语句时必须是排它模式；例如，alter table,drop table。<br />
&#183;执行像insert,update,delete这类DML语句时处于共享模式。它防止其它session对同一个对象同时执行ddl语句。<br />
&#183;任何对象拥有正被改变的数据，TM锁都将必须存在。<br />
&#183;锁指向对象。</p>
<p>　　在TM队列避免竞争，可以考虑屏蔽对象表级锁，屏蔽表级锁防止对象执行任何ddl语句。</p>
<p><strong>ST：空间事务锁</strong><br />
&#183;每个数据库(非实例)拥有一个ST锁。<br />
&#183;除了本地管理表空间，在space管理操作(新建或删除extents)时必须是排它模式。<br />
&#183;对象creation, dropping, extension, 以及truncation都处于这种锁<br />
&#183;多数公共原因的争夺，是在磁盘排序(并非使用真正的临时表空间)或回滚段扩展或收缩。</p>
<p>　按如下项以避免竞争：<br />
　　&#183;使用真正的临时表空间(true temporary tablespaces)，利用临时文件。临时段在磁盘排序之后并不创建或删除。<br />
　　&#183;使用本地管理表空间。<br />
　　&#183;指定回滚段避免动态扩展和收缩，或使用自动undo management。<br />
　　&#183;避免应用执行创建或删除数据库对象。</p>
<p><strong>UL：用户定义锁</strong>用户可以自定义锁。内容较多并与此节关系不大，略过。</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303570.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:23 <a href="http://www.blogjava.net/javaex/articles/303570.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(六)-(2)-V$SESSION_EVENT 转自三思 http://junsansi.itpub.net/post/29894/292375</title><link>http://www.blogjava.net/javaex/articles/303569.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:21:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303569.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303569.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303569.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303569.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303569.html</trackback:ping><description><![CDATA[本视图记录了每个session的每一项等待事件。由上文所知V$SESSION_WAIT显示了session的当前等待事件，而V$SESSION_EVENT则记录了session自启动起所有的事件。
<p><br />
<strong>V$SESSION_EVENT中的常用列</strong><br />
SID：session标识<br />
EVENT：session等待的事件<br />
TOTAL_WAITS：此session当前事件的总等待数<br />
TIME_WAITED：此session总等待时间(单位，百分之一秒)<br />
AVERAGE_WAIT：此session当前事件平均等待时间(单位，百分之一秒)<br />
TOTAL_TIMEOUTS：等待超时次数</p>
<p>其它用法与V$SESSION_WAIT相似，不详述了</p>
<p><br />
附注：</p>
<p>Oracle的等待事件是衡量Oracle运行状况的重要依据及指标。等待事件的概念是在Oracle7.0.1.2中引入的，大致有100个等待事件。在Oracle 8.0中这个数目增加到了大约150个，在Oracle8i中大约有200个事件,在Oracle9i中大约有360个等待事件。主要有两种类别的等待事件，即空闲(idle)等待事件和非空闲(non-idle)等待事件。<br />
关于空闲事件和非空闲事件目前通过google可以搜索到非常多详尽的相关信息，同时<br />
Oracle Database Performance Tuning Guide and Reference中关于Wait Events也有非常详尽的描述，在此就不多费口舌了。不过我在itpub论坛看到有热心人整理的chm格式非空闲事件说明，有兴趣的朋友可以下载，链接如下：<br />
非空闲事件说明<br />
</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303569.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:21 <a href="http://www.blogjava.net/javaex/articles/303569.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习动态性能表(七)--V$PROCESS 转自三思 http://junsansi.itpub.net/post/29894/292558</title><link>http://www.blogjava.net/javaex/articles/303568.html</link><dc:creator>javaex</dc:creator><author>javaex</author><pubDate>Wed, 25 Nov 2009 02:19:00 GMT</pubDate><guid>http://www.blogjava.net/javaex/articles/303568.html</guid><wfw:comment>http://www.blogjava.net/javaex/comments/303568.html</wfw:comment><comments>http://www.blogjava.net/javaex/articles/303568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaex/comments/commentRss/303568.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaex/services/trackbacks/303568.html</trackback:ping><description><![CDATA[本视图包含当前系统oracle运行的所有进程信息。常被用于将oracle或服务进程的操作系统进程ID与数据库session之间建立联系。在某些情况下非常有用：
<p>1.如果数据库瓶颈是系统资源(如：cpu,内存)，并且占用资源最多的用户总是停留在某几个服务进程，那么进行如下诸项：</p>
<p>1&gt;.找出资源进程<br />
2&gt;.找出它们的session,你必须将进程与会话联系起来。<br />
3&gt;.找出为什么session占用了如此多的资源</p>
<p>2.SQL跟踪文件名是基于服务进程的操作系统进程ID。要找出session的跟踪文件，你必须将session与服务进程联系起来。<br />
3.某些事件，如rdbms ipc reply，鉴别session进程的Oracle进程ID在等什么。要发现这些进程在做什么，你必须找出它们的session。<br />
4.你所看到的服务器上的后台进程(DBWR,LGWR,PMON等)都是服务进程。要想知道他们在做什么，你必须找到他们的session。</p>
<p><strong>V$PROCESS中的常用列</strong><br />
ADDR：进程对象地址<br />
PID：oracle进程ID<br />
SPID：操作系统进程ID</p>
<p><strong>V$PROCESS中的连接列</strong><br />
Column View Joined Column(s) <br />
ADDR V$SESSION PADDR</p>
<p><strong>示例：</strong><br />
1.查找指定系统用户在oracle中的session信息及进程id，假设操作系统用户为：junsansi<br />
select s.sid,s.SERIAL#, s.username,p.spid<br />
from v$session s, v$process p<br />
where s.osuser = 'junsansi'<br />
and s.PADDR = p.ADDR</p>
<p>2.查看锁和等待<br />
SELECT /*+ rule */<br />
lpad(' ', decode(l.xidusn, 0, 3, 0)) || l.oracle_username User_name,<br />
o.owner,o.object_name,o.object_type,s.sid,s.serial#,p.spid<br />
FROM v$locked_object l, dba_objects o, v$session s, v$process p<br />
WHERE l.object_id = o.object_id<br />
AND l.session_id = s.sid and s.paddr = p.addr<br />
ORDER BY o.object_id, xidusn DESC</p>
<p><strong>附注：</strong><br />
　　在linux环境可以通过ps查看进程信息包括pid,windows中任务管理器的PID与v$process中pid不能一一对应，这块在oracleDocument中也没有找到介绍，后来google了一下，有资料介绍说是由于windows是多线程服务器,每个进程包含一系列线程。这点于unix等不同，Unix每个Oralce进程独立存在，在Nt上所有线程由Oralce进程衍生。<br />
　　要在windows中显示oracle相关进程pid，我们可以通过一个简单的sql语句来实现。<br />
SELECT s.SID, p.pid, p.spid signaled, s.osuser, s.program<br />
FROM v$process p, v$session s<br />
WHERE p.addr = s.paddr;</p>
<p>SID PID SIGNALED OSUSER PROGRAM <br />
1 2 2452 SYSTEM ORACLE.EXE <br />
2 3 2460 SYSTEM ORACLE.EXE <br />
3 4 2472 SYSTEM ORACLE.EXE <br />
4 5 2492 SYSTEM ORACLE.EXE <br />
5 6 2496 SYSTEM ORACLE.EXE <br />
6 7 2508 SYSTEM ORACLE.EXE <br />
7 8 2520 SYSTEM ORACLE.EXE <br />
8 9 2524 SYSTEM ORACLE.EXE <br />
10 12 1316 JSSjunsansi PlSqlDev.exe <br />
9 13 3420 JSSjunsansi PlSqlDev.exe <br />
13 14 660 JSSjunsansi PlSqlDev.exe </p>
<p>还可以通过和 v$bgprocess 连接查询到后台进程的名字： <br />
SELECT s.SID SID, p.spid threadid, p.program processname, bg.NAME NAME<br />
FROM v$process p, v$session s, v$bgprocess bg<br />
WHERE p.addr = s.paddr<br />
AND p.addr = bg.paddr<br />
AND bg.paddr &lt;&gt; '00';</p>
<p>SID THREADID PROCESSNAME NAME <br />
1 2452 ORACLE.EXE PMON <br />
2 2460 ORACLE.EXE DBW0 <br />
3 2472 ORACLE.EXE LGWR <br />
4 2492 ORACLE.EXE CKPT <br />
5 2496 ORACLE.EXE SMON <br />
6 2508 ORACLE.EXE RECO <br />
7 2520 ORACLE.EXE CJQ0 <br />
8 2524 ORACLE.EXE QMN0 </p>
<p>Eygle大师写了一段sql脚本getsql.sql，用来获取指定pid正在执行的sql语句，在此也附注上来。<br />
REM getsql.sql<br />
REM author eygle<br />
REM 在windows上,已知进程ID,得到当前正在执行的语句<br />
REM 在windows上,进程ID为16进制,需要转换,在UNIX直接为10进制<br />
SELECT /*+ ORDERED */<br />
sql_text<br />
FROM v$sqltext a<br />
WHERE (a.hash_value, a.address) IN (<br />
SELECT DECODE (sql_hash_value,<br />
0, prev_hash_value,<br />
sql_hash_value<br />
),<br />
DECODE (sql_hash_value, 0, prev_sql_addr, sql_address)<br />
FROM v$session b<br />
WHERE b.paddr = (SELECT addr<br />
FROM v$process c<br />
WHERE c.spid = TO_NUMBER ('&amp;pid', 'xxxx')))<br />
ORDER BY piece ASC<br />
/</p>
<img src ="http://www.blogjava.net/javaex/aggbug/303568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaex/" target="_blank">javaex</a> 2009-11-25 10:19 <a href="http://www.blogjava.net/javaex/articles/303568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>