副标题[/!--empirenews.page--]
DBMS_JOB系统包是Oracle“任务队列”子系统的API编程接口。 DBMS_JOB包对于任务队列提供了下面这些功能:提交并且执行一个任务、改变任务的执行参数以及删除或者临时挂起任务等。 DBMS_JOB包是由ORACLE_HOME目录下的rdbms/admin子目录下的DBMSJOB.SQL和PRVTJOB.PLB 这两个脚本文件创建的。 这两个文件被CATPROC.SQL脚本文件调用,而CATPROC.SQL这个文件一般是在数据库创建后立即执行的。 脚本为DBMS_JOB包创建了一个公共同义词,并给该包授予了公共的可执行权限,所以所有的Oracle用户均可以使用这个包。
下面几个数据字典视图是关于任务队列信息的,主要有DBA_JOBS,USER_JOBS和DBA_JOBS_RUNNING。 这些字典视图是由名为CATJOBQ.SQL的脚本文件创建的。该脚本文件和创建DBMS_JOB包的脚本文件一样在ORACLE_HOME目录的rdbms/admin子目录中,同样也是由脚本文件CATPROC.SQL调用。 最后,要使任务队列能正常运行,还必须启动它自己专有的后台过程。 启动后台过程是通过在初始化文件init*.ora(实例不同,初始化文件名也略有不同)中设置初始化参数来进行的。下面就是该参数: JOB_QUEUE_PROCESSES = n 其中,n可以是0到36之间的任何一个数。除了该参数以外,还有几个关于任务队列的初始化参数,本文后面将会对其进行详细讨论。 DBMS_JOB包中包含有许多过程,见表1所示。
表1 DBMS_JOB包 名称 类型 描述 DBMS_JOB.ISUBMIT 过程 提交一个新任务,用户指定一个任务号 DBMS_JOB.SUBMIT 过程 提交一个新任务,系统指定一个任务号 DBMS_JOB.REMOVE 过程 从队列中删除一个已经存在的任务 DBMS_JOB.CHANGE 过程 更改用户设定的任务参数 DBMS_JOB.WHAT 过程 更改PL/SQL任务定义 DBMS_JOB.NEXT_DATE 过程 更改任务下一次运行时间 DBMS_JOB.INTERVAL 过程 更改任务运行的时间间隔 DBMS_JOB.BROKEN 过程 将任务挂起,不让其重复运行 DBMS_JOB.RUN 过程 在当前会话中立即执行任务 DBMS_JOB.USER_EXPORT 过程 创建文字字符串,用于重新创建一个任务
三、DBMS_JOB包参数 DBMS_JOB包中所有的过程都有一组相同的公共参数,用于定义任务,任务的运行时间以及任务定时运行的时间间隔。 这些公共任务定义参数见表2所示。
表2 DBMS_JOB过程的公共参数 名称 类型 注释 Job BINARY_INTEGER 任务的唯一识别号 What VARCHAR2 作为任务执行的PL/SQL代码 Next_date VARCHAR2 任务下一次运行的时间 Interval VARCHAR2 日期表达式,用来计算下一次任务运行的时间
下面我们来详细讨论这些参数的意义及用法。 1、job 参数job是一个整数,用来唯一地标示一个任务。该参数既可由用户指定也可由系统自动赋予,这完全取决于提交任务时选用了那一个任务提交过程。DBMS_JOB.SUBMIT过程通过获得序列SYS.JOBSEQ的下一个值来自动赋予一个任务号。 该任务号是作为一个OUT参数返回的,所以调用者随后可以识别出提交的任务。而DBMS_JOB.ISUBMIT过程则由调用者给任务指定一个识别号,这时候,任务号的唯一性就完全取决于调用者了。 除了删除或者重新提交任务,一般来说任务号是不能改变的。即使当数据库被导出或者被导入这样极端的情况,任务号也将被保留下来。 所以在执行含有任务的数据的导入/导出操作时很可能会发生任务号冲突的现象。
2、what what参数是一个可以转化为合法PL/SQL调用的字符串,该调用将被任务队列自动执行。 在what参数中,如果使用文字字符串,则该字符串必须用单引号括起来。 what参数也可以使用包含我们所需要字符串值的VARCHAR2变量。 实际的PL/SQL调用必须用分号隔开。在PL/SQL调用中如果要嵌入文字字符串,则必须使用两个单引号。 what参数的长度在Oracle7.3中限制在2000个字节以内,在Oracle 8.0以后,扩大到了4000个字节,这对于一般的应用已完全足够。 该参数的值一般情况下都是对一个PL/SQL存储过程的调用。在实际应用中,尽管可以使用大匿名Pl/SQL块,但建议大家最好不要这样使用。 还有一个实际经验就是最好将存储过程调用封装在一个匿名块中,这样可以避免一些比较莫名错误的产生。 我来举一个例子,一般情况下,what参数可以这样引用: what =>’my_procedure(parameter1);’ 但是比较安全的引用,应该这样写: what =>’begin my_procedure(parameter1); end;’ 任何时候,我们只要通过更改what参数就可以达到更改任务定义的目的。 但是有一点需要注意,通过改变what参数来改变任务定义时,用户当前的会话设置也被记录下来并成为任务运行环境的一部分。 如果当前会话设置和最初提交任务时的会话设置不同,就有可能改变任务的运行行为。 意识到这个潜在的副作用是非常重要的,无论何时只要应用到任何DBMS_JOB过程中的what参数时就一定要确保会话设置的正确。
3、next_date Next_date参数是用来调度任务队列中该任务下一次运行的时间。这个参数对于DBMS_JOB.SUBMIT和DBMS_JOB.BROKEN这两个过程确省为系统当前时间,也就是说任务将立即运行。 当将一个任务的next_date参数赋值为null时,则该任务下一次运行的时间将被指定为4000年1月1日,也就是说该任务将永远不再运行。 在大多数情况下,这可能是我们不愿意看到的情形。但是,换一个角度来考虑,如果想在任务队列中保留该任务而又不想让其运行,将next_date设置为null却是一个非常简单的办法。Next_date也可以设置为过去的一个时间。 这里要注意,系统任务的执行顺序是根据它们下一次的执行时间来确定的,于是将next_date参数设置回去就可以达到将该任务排在任务队列前面的目的。 这在任务队列进程不能跟上将要执行的任务并且一个特定的任务需要尽快执行时是非常有用的。
4、Interval Internal参数是一个表示Oracle合法日期表达式的字符串。 这个日期字符串的值在每次任务被执行时算出,算出的日期表达式有两种可能,要么是未来的一个时间要么就是null。 这里要强调一点:很多开发者都没有意识到next_date是在一个任务开始时算出的,而不是在任务成功完成时算出的。 当任务成功完成时,系统通过更新任务队列目录表将前面算出的next_date值置为下一次任务要运行的时间。 当由interval表达式算出next_date是null时,任务自动从任务队列中移出,不会再继续执行。 因此,如果传递一个null值给interval参数,则该任务仅仅执行一次。 通过给interval参数赋各种不同的值,可以设计出复杂运行时间计划的任务。本文后面的“任务间隔和日期算法”将对interval表达式进行详细讨论,并给出一个实际有用interval表达式的例子。
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|