我试图从dba_scheduler_job_run_details视图中获取值。 其中log_date> (SYSDATE - 5 /(24 * 60))(即最后5分钟的数据)
但它没有为我提供正确的价值。
如需样品,请查看以下数据: SQL查询:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE LOG_DATE > (SYSDATE - 5/(24*60))
ORDER BY LOG_DATE DESC;
答案 0 :(得分:2)
这是因为log_date
是timestamp with timezone
数据类型,当你使用date数据类型加入它时,当Oracle进行隐式转换比较时,它会导致两个不同的时间:
SQL> SELECT SYSTIMESTAMP, CAST(SYSDATE AS TIMESTAMP WITH TIME ZONE) time_with_tz FROM dual;
SYSTIMESTAMP TIME_WITH_TZ
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
19-MAR-18 09.57.07.654161 AM -04:00 19-MAR-18 09.57.07.000000 AM +05:30
因此,如果我在偏移量为-4:00的服务器上执行偏移量为+5:30的时区查询,Oracle会将SYSDATE - 5/(24*60)
转换为sysdate - (9:30 + 0:05)
。
告诉Oracle明确地将log_date转换为日期,然后按照以下方式应用> (SYSDATE - 5/(24*60)
的文件管理器,你会没事的:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE cast(LOG_DATE AS DATE) > (SYSDATE - 5/(24*60))
ORDER BY LOG_DATE DESC;
更新:由于以下原因,此查询可能存在性能问题,
1)Oracle将转换LOG_DATE列的每一行的数据类型 到目前为止的时区的时间戳。
2)LOG_DATE列的构建索引(如果有)将不会使用到期 到CAST功能。
更好的解决方案是将sysdate - 5 /(24 * 60)转换为带时区的时间戳,您必须知道Oracle服务器的时区,假设服务器位于UTC -4:00,下面查询应该可以正常工作:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE LOG_DATE > TO_TIMESTAMP_TZ (to_char(SYSDATE - 5/(24*60), 'YYYY-MM-DD HH24:MI:SS') || ' -4:00', 'YYYY-MM-DD HH24:MI:SS TZH:TZM')
ORDER BY LOG_DATE DESC;
@mathguy建议的另一种更简单的方法,使用INTERVAL函数:
SELECT SYSDATE, SYSDATE - 5/(24*60),LOG_DATE,TRUNC(LOG_DATE),TO_CHAR(LOG_DATE,'YYYY/MM/DD HH:MI:SS')
FROM dba_scheduler_job_run_details
WHERE LOG_DATE > SYSTIMESTAMP - INTERVAL '5' MINUTE
ORDER BY LOG_DATE DESC;