Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 日期函数面临的问题_Oracle_Date - Fatal编程技术网

Oracle 日期函数面临的问题

Oracle 日期函数面临的问题,oracle,date,Oracle,Date,我试图从dba\u调度程序\u作业\u运行\u详细信息视图中获取该值。 其中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

我试图从dba\u调度程序\u作业\u运行\u详细信息视图中获取该值。 其中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;
o/p:
附加图像

这是因为
log_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显式地将日志日期转换为日期,然后应用
>(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\u DATE from列的每一行的数据类型 带有截止日期时区的时间戳

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建议的另一种更简单的方法是使用区间函数:

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;

这是因为
log\u 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显式地将日志日期转换为日期,然后应用
>(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\u DATE from列的每一行的数据类型 带有截止日期时区的时间戳

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建议的另一种更简单的方法是使用区间函数:

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;

HH:MM:SS
-您正在显示小时和秒之间的月数。您应该在问题输入错误时删除它。
HH:MM:SS
-您正在小时和秒之间显示月数。您应该在问题输入错误时删除它。更好(假设使用的“时区”相同)-将日志日期与SYSTIMESTAMP而不是SYSDATE进行比较。@mathguy谢谢您的建议,我已更新了答案。只是想知道是否还有更好的解决方案。可能有。我假设
LOG\u DATE
是服务器时区中的时间戳。(很抱歉,我不在该行业工作;我没有机会与调度器一起工作。)如果是这样,那么测试
LOG\u DATE>SYSTIMESTAMP-间隔“5”分钟就简单多了。更一般地说,
LOG\u DATE
应该与返回当前时间戳的函数进行比较,该函数的时区与
LOG\u DATE
的时区相同。更好(假设使用的“时区”相同)-将LOG\u DATE与SYSTIMESTAMP而不是SYSDATE进行比较。@mathguy感谢您的建议,我已经更新了答案。只是想知道是否还有更好的解决方案。可能有。我假设
LOG\u DATE
是服务器时区中的时间戳。(很抱歉,我不在该行业工作;我没有机会与调度器一起工作。)如果是这样,那么测试
LOG\u DATE>SYSTIMESTAMP-间隔“5”分钟就简单多了。更一般地说,
LOG\u DATE
应该与返回当前时间戳的函数进行比较,该时间戳的时区与
LOG\u DATE
的时区相同。