Oracle中通过命令行实现定时操作详解Oracle中通过命令行实现定时操作详解Oracle基础
众所周知一般操作系统会提供定时执行任务的方法例如Unix平台上提供了让系统定时执行任务的命令Crontab但是对于某些需求例如一些对数据库表的操作最为典型的是证券交易所每日收盘后的结算它涉及大量的数据库表操作如果仍然利用操作系统去定时执行不仅需要大量的编程工作而且还会出现用户不一致等运行错误甚至导致程序无法执行
一分析问题
事实上对于以上需求我们可以利用数据库本身拥有的功能Job Queue(任务队列管理器)去实现任务队列管理器允许用户提前调度和安排某一任务使其能在指定的时间点或时间段内自动执行一次或多次由于任务在数据库中被执行所以执行效率很高
任务队列管理器允许我们定制任务的执行时间并提供了灵活的处理方式还可以通过配置安排任务在系统用户访问量少的时段内执行极大地提高了工作效率例如对于数据库日常的备份更新删除和复制等耗时长重复性强的工作我们就可以利用任务队列管理器去自动执行以减少工作量
目前拥有此项功能的数据库有许多最有代表性的是SQL Server Oracle 等但是要让任务队列管理器工作还需要我们加以配置才能实现SQL Server的功能配置是在一个图形化界面(GUI)中实现的非常简单利用OEM客户端管理工具Oracle的配置也可以在一个图形界面中完成然而大多数的用户更习惯于命令行的方式去操纵数据库本文介绍如何通过命令行实现这种配置
二实现步骤
.确保Oracle的工作模式允许启动任务队列管理器
Oracle定时执行Job Queue的后台程序是SNP进程而要启动SNP进程首先要确保整个系统的模式是可以启动SNP进程的这需要以DBA的身份去执行如下命令
svrmgrl> alter system enable restricted session;
或sql> alter system disenable restricted session;
利用如上命令更改系统的会话方式为disenable restricted为SNP的启动创造条件
.确保Oracle的系统已经配置了任务队列管理器的启动参数
SNP的启动参数位于Oracle的初始化文件中该文件放在$ORACLE_HOME/dbs路径下如果Oracle的SID是myora的话则初始化文件就是initmyoraora在文件中对SNP启动参数的描述部分如下
job_queue_process=n
job_queue_interval=N
第一行定义SNP进程的启动个数为n系统缺省值为正常定义范围为~根据任务的多少可以配置不同的数值
第二行定义系统每隔N秒唤醒该进程一次系统缺省值为秒正常范围为~秒事实上该进程执行完当前任务后就进入睡眠状态睡眠一段时间后由系统的总控负责将其唤醒
如果该文件中没有上面两行请按照如上配置添加配置完成后需要重新启动数据库使其生效注意如果任务要求执行的间隔很短的话N的配置也要相应地小一点
.将任务加入到数据库的任务队列中
调用Oracle的dbms_job包中的存储过程将任务加入到任务队列中
dbms_jobsubmit( job out binary_integer
whatinarchar
next_date indate
intervalinvarchar
no_parseinboolean)
其中
●job输出变量是此任务在任务队列中的编号
●what执行的任务的名称及其输入参数
●next_date任务执行的时间
●interval任务执行的时间间隔
下面详细讨论一下dbms_jobsubmit中的参数interval严格地讲interval是指上一次执行结束到下一次开始执行的时间间隔当interval设置为null时该job执行结束后就被从队列中删除假如我们需要该job周期性地执行则要用sysdate+m表示
将任务加入到任务队列之前要确定执行任务的数据库用户若用户是scott 则需要确保该用户拥有执行包dbms_job的权限若没有需要以DBA的身份将权利授予scott用户
svrmgrl> grant execute on dbms_job to scott;
.将要执行的任务写成存储过程或其他的数据库可执行的pl/sql程序段
例如我们已经建立了一个存储过程其名称为my_job在sql/plus中以scott用户身份登录执行如下命令
sql> variable n number;
sql> begin
dbms_jobsubmit(:nmy_job;sysdate
sysdate+/);
commit;
end;
/
系统提示执行成功
Sql> print :n;
系统打印此任务的编号例如结果为
如上我们创建了一个每隔分钟执行一次的任务号为的任务可以通过Oracle提供的数据字典user_jobs察看该任务的执行情况
sql> select jobnext_datenext_secfailuresbroken from user_jobs;
执行结果如下
job next_date next_sec failures broken
// :: N
这表示任务号为的任务下一次将在// ::执行此任务的执行失败记录为次注意当执行job出现错误时Oracle将其记录在日志里失败次数每次自动加当执行失败次数达到时Oracle就将该job标志为broken此后Oracle不再继续执行它直到用户调用过程dbms_jobbroken重新设置为not broken或强制调用dbms_jobrun来重新执行它
除了以上我们讨论的submit存储过程之外Oracle还提供了其他许多存储过程来操作任务例如dbms_jobchange dbms_jobwhatdbms_jobinterval可以用来修改提交的任务要想删除该任务只需运行dbms_jobremove(n)即可其中n为任务号