oracle中每月调用一次,JOB——手工指定Oracle中job执行的时间间隔
一、JOB时间间隔的问题
我们MIS系统中需要建立一些JOB,比如客户会要求在月底自动生成一些报表统计信息。
在指定JOB的执行时间时,一般我们会选择在每月月底的午夜来执行(或者有多个JOB,应该分散在不同的时间段来执行)。此时不能直接用sysdate来确定时间,因为每次执行后,oracle自动生成的下一次的执行时间,会有几秒的延迟。
比如,我指定第一次执行时间为:2008-03-27 10:58:01,时间间隔的方式为:last_day(add_months(sysdate, 1))。
那么,JOB执行后我会发现,第一次的执行时间是2008-03-27 10:58:05,而下一次的执行时间被更新为2008-04-30 10:58:05;而下次执行后,发现它的执行时间是2008-04-30 10:58:07,而它再次执行的时间变为2008-05-31 10:58:07;……
二、可能原因
(1)JOB的调用有时间延迟。我指定在10:58:01执行,可是由于延迟,真正执行的时间是10:58:05;
(2)根据实际的执行时间来自动计算下一次的执行时间。我指定下一次的时间计算方法是last_day(add_months(sysdate, 1))。但它是根据10:58:05来计算的,而不是10:58:01。
三、解决办法
这种延迟累计起来,就可能导致执行时间错误!为避免这种延迟,我们应该手工指定执行时间中的“时分秒”。比如,
每月月底的午夜:
last_day(add_months(to_date(to_char(sysdate, 'yyyy-mm-dd'), 'yyyy-mm-dd'), 1))
每月的任意指定时间:
last_day(add_months(to_date(to_char(sysdate, 'yyyy-mm-dd') || ' 11:24:31', 'yyyy-mm-dd hh24:mi:ss'), 1))
……
这样,每次执行的时间大概会比指定的时间延迟2-5秒,但oracle自动计算出来的下一次执行时间是没有问题的,所以不会累计这个延迟。
四、相关测试
下面是一个小测试:
SQL> conn tianyc/test
已连接。
SQL> select * from v$version;
BANNER
-----------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE 9.2.0.1.0 Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production
-- 1. 创建初始环境
-- 1.1 创建表test_job,存放执行日期SQL> create table test_job ( a date );
表已创建。
-- 1.2 创建过程,向表test_job中插入执行时的日期
SQL> CREATE OR REPLACE PROCEDURE PRC_TEST_JOB(PRM_A IN DATE,
2 PRM_APPCODE OUT NUMBER,
3 PRM_ERRORMSG OUT VARCHAR2)
4 IS
5 BEGIN
6 PRM_APPCODE := 1;
7 PRM_ERRORMSG := 'succeed';
8 INSERT INTO test_job VALUES(prm_a);
9 COMMIT;
10 END PRC_TEST_JOB;
11
12 /
过程已创建。
-- 2. 创建任务
-- 2.1 查看当前时间,用来确定创建的任务的执行时间
SQL> select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2008-03-27 10:52:20
-- 2.2 创建任务,调用步骤1.2中创建的过程。在10:58:01时执行。
SQL> variable x number;
SQL> begin
2 sys.dbms_job.submit(job => :x,
3 what => 'DECLARE
4 n_appcode NUMBER(10);
5 v_errormsg VARCHAR2(4000);
6 BEGIN
7 prc_test_job(SYSDATE, n_appcode, v_errormsg);
8 END;',
9 next_date => to_date('27-03-2008 10:58:01', 'dd-mm-yyyy hh24:mi:ss'),
10 interval => 'last_day(add_months(sysdate, 1))');
11 commit;
12 end;
13 /
PL/SQL 过程已成功完成。
-- 3. 验证数据
-- 3.1 在该执行时间之前没有数据
SQL> select * from test_job;
未选定行
SQL> select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2008-03-27 10:57:46
-- 3.2 过了该时间后,可以查询到数据
SQL> select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2008-03-27 10:58:18
SQL> select to_char(a, 'yyyy-mm-dd hh24:mi:ss') from test_job;
TO_CHAR(A,'YYYY-MM-
-------------------
2008-03-27 10:58:05
-- 3.3 任务执行完毕后,自动根据条件(INTERVAL)更新下次的执行时间(NEXT_DATE)
SQL> select PRIV_USER, LAST_DATE, NEXT_DATE, INTERVAL from user_jobs;
PRIV_USER LAST_DATE NEXT_DATE INTERVAL
------------------------------ ---------- ---------- ----------------------------------
TIANYC 27-3月 -08 30-4月 -08 last_day(add_months(sysdate, 1))
SQL> select what from user_jobs;
WHAT
-------------------------------------------------------------------------------
DECLARE
n_appcode NUMBER(10);
v_errormsg VARCHAR2(4000);
BEGIN
prc_test_job(SYSDATE, n_appcode, v_errormsg);
END;
SQL>
-- 4. 存在问题:
-- 4.1 test_job里的执行时间不是10:58:01, 而是10:58:05:
SQL> select to_char(a, 'yyyy-mm-dd hh24:mi:ss') from test_job;
TO_CHAR(A,'YYYY-MM-
-------------------
2008-03-27 10:58:05
-- 4.2 在视图user_jobs里也是如此。把这两个时间精确到秒,看看效果:
SQL> select PRIV_USER, to_char(LAST_DATE, 'yyyy-mm-dd hh24:mi:ss'),
2 to_char(NEXT_DATE, 'yyyy-mm-dd hh24:mi:ss'), INTERVAL from user_jobs;
PRIV_USER TO_CHAR(LAST_DATE,' TO_CHAR(NEXT_DATE,' INTERVAL
---------- ------------------- ------------------- --------------------------------
TIANYC 2008-03-27 10:58:05 2008-04-30 10:58:05 last_day(add_months(sysdate, 1))
SQL>
-- 4.3 经过多次测试,每次执行时并不是按照上次指定的秒执行的,而是滞后几秒。这样累计起来,就可能导致执行日期的错误。
-- 所以要想每次都精确地按照秒来执行job,应该手工来指定时间。比如:
-- 4.3.1 在每个月的月底的午夜执行
SQL> select to_char(last_day(add_months(to_date(to_char(sysdate, 'yyyy-mm-dd'), 'yyyy-mm-dd'), 1)), 'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(LAST_DAY(AD
-------------------
2008-04-30 00:00:00
-- 4.3.2 在每个月的月底的任意指定时间执行(这里我指定时间为11:24:31)
SQL> select to_char(last_day(add_months(to_date(to_char(sysdate, 'yyyy-mm-dd') || ' 11:24:31', 'yyyy-mm-dd hh24:mi:ss'), 1)), 'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(LAST_DAY(AD
-------------------
2008-04-30 11:24:31
SQL>
oracle中每月调用一次,JOB——手工指定Oracle中job执行的时间间隔相关推荐
- C语言:从键盘中输入字符串,追加填写到指定文件中
/*从键盘中输入字符串,追加填写到指定文件中*/ #include <stdio.h> #include <string.h> #include <ctype.h> ...
- c++语言程序中,要调用的函数必须在main()函数中定义,惠州学院C++考试复习题
惠州学院C++复习题 一.选择题 1.C++的源文件的扩展名是_____C____. A.h B.obj C.cpp D.exe 2.下列选项能够作为C++变量名的是___C____. A.false ...
- c语言中怎么调用自己定义的函数,c语言中怎么调用自己定义的函数?
一,函数调用的一般形式为: 函数名(实参列表); 实参可以是常数.变量.表达式等,多个实参用逗号,分隔. 在C语言中,函数调用的方式有多种,例如: 在函数调用中还应该注意的一个问题是求值顺序的问题.所 ...
- ImpREC手工指定IAT中的表项值
前言 在做Armadillo1.x的脱壳练习, 找OEP, 脱壳还是一样的. 但是在IAT修复时, 遇到了新知识点. 我找到了壳代码写IAT表项的代码, 由于很乱, 没有找到合适的点来修改(让壳代码写 ...
- python类中方法调用自己类的方法_python 类中方法总结 --- 实例方法、类方法、静态方法...
在python的类语法中,可以出现三种方法,具体如下: (1)实例方法 1)第一个参数必须是实例本身,一般使用[self]表示. 2)在实例方法中,可以通过[self]来操作实例属性,[类名]来操作类 ...
- oracle中每月调用一次,Oracle Job的使用(定时执行)
转载自:https://www.cnblogs.com/Chestnuts/articles/7066333.html oracle中的job能为你做的就是在你规定的时间格式里执行存储过程,定时执行一 ...
- java中如何调用自身结构_如何在Java中的自定义异常中设置我自己的消息,可以检索我的getMessage()但是没有使用构造函数,有什么办法吗?...
我刚学习 Java中的异常处理.我想知道的不是尝试说: throw new Exception("My Message"); 和 String message=ex.getMess ...
- Android中实现调用摄像头拍照并显示在ImageView中
场景 点击拍照按钮调用系统摄像机进行拍照,并将拍的照片显示在ImageView中. 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的 ...
- c语言中被调用函数只需在主调函数中声明,其他函数中不用声明,求助,函数在其他函数中使用时要先声明后调用,这个没声明就用了...
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 如题,程序如下: #include #include //malloc,calloc,free,realloc头文件 #define LEN sizeof ...
- oracle数据库扩大表空间,[小技巧]手工扩大Oracle数据库表空间的方法
1.首先查看表空间的名字和所属文件select tablespace_name, file_id, file_name,round(bytes/(1024*1024),0) total_spacefr ...
最新文章
- matlab外部接口简介
- 基于DDD的.NET开发框架 - ABP领域服务
- checkbox选中和不选中 jqu_jquery checkbox 选中不选中
- 站立会议(11月19日)
- power iso linux启动盘,Power ISO Maker/ISO燃烧到磁盘工具 V3.0版
- Java 创建线程的三种方式
- PSD分层电商促销模板|季末大促上演
- Spring MVC JSR-303验证框架之Hibernate-Validator
- sublime text3 Package Control 插件安装及推荐(MAC)
- 约数国王c语言,求最大公约数问题
- JSON解析方式 gson
- PaddlePaddle(8)—— 如何写好一篇高质量的精选项目
- android 样式预处理,基于Android平台的字符识别预处理算法设计与实现
- QML 环形进度条canvas 98行代码实现
- 在Centos操作系统下安装mysql8.0
- VXLAN技术——数据中心底层技术
- Nginx: 104: Connection reset by peer 错误
- LeetCode08 有效的数独
- 面试B站,结果面试官牵着一条狗出来面试我....这是什么操作??
- 2023银行校园招聘简历自我评价高分写法模板
热门文章
- C语言基础:C语言宏定义(2) - 带参数的宏定义
- Xamarin Android中引用Jar包的方法
- 通过和函数名相同的字符串调用函数 --浅谈loadstring函数
- mysql 51.数据库下载_Database Master官方下载_MySQL/SQLite数据库管理软件V5.2.51.18513下载(暂未上线)_预约_飞翔下载...
- 微信怎么at所有人_变速箱报废、发动机故障、车门下沉,全新马自达3到底怎么了?...
- Spring-BeanPostProcessor的执行顺序
- Spring中注册Bean的方式有哪些?
- SQL查找是否存在,别再count了
- 警惕!这5种“脸色”在暗示你这些健康问题!
- Windows服务器配置fileZilla Server