我有一个 Oracle 12c 数据库,其中我检测到计划的作业在服务器上的时间更改后相隔一小时运行,检查数据库我发现SYSTIMESTAMP与DBTIMEZONE不同
SQL> select dbtimezone, sessiontimezone from dual;
数据库时区
会话时区
-04:00 -05:00
在我运行的操作系统中:date + "%Z%z"
CST -0500
SYSTIMESTAMP和DBTIMEZONE的这些值不一样对吗,当时间改变的时候是不是需要在数据库中修改一些东西呢?
如果您发现数据库的时区不正确,并且您确定这会导致问题(我以前见过),您可以更改它。
set_time_zone_clause::=
例如:
您可以设置一个命名时区,例如:
或固定值:
我用的是前者。然后重启数据库:
请记住,这可能并不总是有效,因为:
此外,您还应该应用最新的 DST 补丁,以便数据库知道何时将时间设置为向前或向后设置夏令时。
调度程序作业是时区感知的,因此如果您将作业 A 安排在 13:00 +11:00,作业 B 安排在 13:05 'Australia/NSW',那么作业 B 将在澳大利亚夏季期间作业 A 之后 5 分钟和之前 55 分钟运行澳大利亚冬季期间的工作 A。
用于
select owner, job_name, to_char(start_date,'TZR') tz from all_scheduler_jobs
确定您请求作业运行的时区。如果您使用的是 12.2,则可以使用
dbms_scheduler.set_attribute(job_name,'NLS_ENV',....);
修改设置。您可能需要select dbms_metadata.get_ddl('PROCOBJ',job_name) from dual;
制定完整的 NLS_ENV 设置集。如果您在 12.2 之前,我相信您需要放弃该作业并从设置了所需时区的会话中重新创建它。
什么都忘了
DBTIMEZONE
,它没有实际用途。DBTIMEZONE的唯一目的是:它定义(内部)时区来存储TIMESTAMP WITH LOCAL TIME ZONE
值 - 仅此而已。TIMESTAMP WITH LOCAL TIME ZONE
因此,当您有一个包含列的表并且该列包含数据时,您无法修改它。SYSTIMESTAMP
(andSYSATE
) 以数据库服务器操作系统的时区返回!因此,它们当然可以不同。
处理SCHEDULER JOBS 的时区和夏令时非常复杂。查看日历语法文档:
另请参阅https://stackoverflow.com/questions/29271224/how-to-handle-day-light-saving-in-oracle-database/29272926#29272926