有些job中跑应用程序,希望记下时间戳,但是取了current_timestamp之后,发现时间和实际的时间不准,查了几个小时。这是因为在job中跑的时候,current_timestamp是GMT格林尼治时间。
见下面的testcase,我们设置数据库服务器的时区是东八区的北京时间;客户端plsql所在的时间是东九区的首尔时间。
--create table for testing
drop table runlog_b;
CREATE TABLE runlog_b AS
SELECT SYSDATE SYS_DATE ,current_timestamp curr_timestamp,SESSIONTIMEZONE sess_timezone,current_date curr_date,
LOCALTIMESTAMP local_timestamp,SYSTIMESTAMP sys_timestamp FROM dual where 1=2;
--create procedure for testing
Create or REPLACE PROCEDURE nested_loop_b IS
BEGIN
insert into runlog_b SELECT SYSDATE,current_timestamp,SESSIONTIMEZONE,current_date,LOCALTIMESTAMP,SYSTIMESTAMP FROM dual;
commit;
END nested_loop_b;
/
--在客户端plsqldev创建job,注:客户端所在的时区是+9:0,数据库服务器端的时区是北京的+8:0,可以看到如下:
SQL> SELECT SYSDATE SYS_DATE ,current_timestamp curr_timestamp,SESSIONTIMEZONE sess_timezone,current_date curr_date,
2 LOCALTIMESTAMP local_timestamp,SYSTIMESTAMP sys_timestamp FROM dual;
SYS_DATE CURR_TIMESTAMP SESS_TIMEZONE CURR_DATE LOCAL_TIMESTAMP SYS_TIMESTAMP
------------------------------ -------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
2014/2/21 11:51:42 21-FEB-14 12.51.42.238619 PM +09:00 +09:00 2014/2/21 12:51:42 21-FEB-14 12.51.42.238619 PM 21-FEB-14 11.51.42.238616 AM +08:00
SQL>
--创建一个job跑上面的存储过程:
SQL> 跑job的结果:
SYS_DATE CURR_TIMESTAMP SESS_TIMEZONE CURR_DATE LOCAL_TIMESTAMP SYS_TIMESTAMP
------------------- ---------------------------------------- -------------------- ------------------- ------------------------------ --------------------------------------------------
2014-02-21 11:00:49 21-FEB-14 03.00.49.010388 AM +00:00 +00:00 2014-02-21 03:00:49 21-FEB-14 03.00.49.010388 AM 21-FEB-14 11.00.49.010371 AM +08:00
2014-02-21 11:03:04 21-FEB-14 03.03.04.063177 AM +00:00 +00:00 2014-02-21 03:03:04 21-FEB-14 03.03.04.063177 AM 21-FEB-14 11.03.04.063174 AM +08:00
2014-02-21 11:06:04 21-FEB-14 03.06.04.137326 AM +00:00 +00:00 2014-02-21 03:06:04 21-FEB-14 03.06.04.137326 AM 21-FEB-14 11.06.04.137303 AM +08:00
drop table runlog_b;
CREATE TABLE runlog_b AS
SELECT SYSDATE SYS_DATE ,current_timestamp curr_timestamp,SESSIONTIMEZONE sess_timezone,current_date curr_date,
LOCALTIMESTAMP local_timestamp,SYSTIMESTAMP sys_timestamp FROM dual where 1=2;
--create procedure for testing
Create or REPLACE PROCEDURE nested_loop_b IS
BEGIN
insert into runlog_b SELECT SYSDATE,current_timestamp,SESSIONTIMEZONE,current_date,LOCALTIMESTAMP,SYSTIMESTAMP FROM dual;
commit;
END nested_loop_b;
/
--在客户端plsqldev创建job,注:客户端所在的时区是+9:0,数据库服务器端的时区是北京的+8:0,可以看到如下:
SQL> SELECT SYSDATE SYS_DATE ,current_timestamp curr_timestamp,SESSIONTIMEZONE sess_timezone,current_date curr_date,
2 LOCALTIMESTAMP local_timestamp,SYSTIMESTAMP sys_timestamp FROM dual;
SYS_DATE CURR_TIMESTAMP SESS_TIMEZONE CURR_DATE LOCAL_TIMESTAMP SYS_TIMESTAMP
------------------------------ -------------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
2014/2/21 11:51:42 21-FEB-14 12.51.42.238619 PM +09:00 +09:00 2014/2/21 12:51:42 21-FEB-14 12.51.42.238619 PM 21-FEB-14 11.51.42.238616 AM +08:00
SQL>
--创建一个job跑上面的存储过程:
SQL> 跑job的结果:
SYS_DATE CURR_TIMESTAMP SESS_TIMEZONE CURR_DATE LOCAL_TIMESTAMP SYS_TIMESTAMP
------------------- ---------------------------------------- -------------------- ------------------- ------------------------------ --------------------------------------------------
2014-02-21 11:00:49 21-FEB-14 03.00.49.010388 AM +00:00 +00:00 2014-02-21 03:00:49 21-FEB-14 03.00.49.010388 AM 21-FEB-14 11.00.49.010371 AM +08:00
2014-02-21 11:03:04 21-FEB-14 03.03.04.063177 AM +00:00 +00:00 2014-02-21 03:03:04 21-FEB-14 03.03.04.063177 AM 21-FEB-14 11.03.04.063174 AM +08:00
2014-02-21 11:06:04 21-FEB-14 03.06.04.137326 AM +00:00 +00:00 2014-02-21 03:06:04 21-FEB-14 03.06.04.137326 AM 21-FEB-14 11.06.04.137303 AM +08:00
可以看到sessiontimezone是+0:0,是格林尼治时间。
因此,如果我们要在job取时间戳,可以取systimestamp这个值。这个值是DB服务器上的时间的时间戳。
或者用加一条set time_zone也是一样的效果:
Create or REPLACE PROCEDURE nested_loop_b IS
BEGIN
execute immediate 'alter session set time_zone = ''+08:00''';
insert into runlog_b SELECT SYSDATE,current_timestamp,SESSIONTIMEZONE,current_date,LOCALTIMESTAMP,SYSTIMESTAMP FROM dual;
commit;
END nested_loop_b;
/
--
SYS_DATE CURR_TIMESTAMP SESS_TIMEZONE CURR_DATE LOCAL_TIMESTAMP SYS_TIMESTAMP
------------------- --------------------------------------------------------------------------- ------------------------------ ------------------------------ ------------------------------ --------------------------------------------------
2014-02-21 12:03:01 21-FEB-14 12.03.01.035054 PM +08:00 +08:00 2014-02-21 12:03:01 21-FEB-14 12.03.01.035054 PM 21-FEB-14 12.03.01.035051 PM +08:00
2014-02-21 12:06:01 21-FEB-14 12.06.01.108673 PM +08:00 +08:00 2014-02-21 12:06:01 21-FEB-14 12.06.01.108673 PM 21-FEB-14 12.06.01.108671 PM +08:00
SQL>
BEGIN
execute immediate 'alter session set time_zone = ''+08:00''';
insert into runlog_b SELECT SYSDATE,current_timestamp,SESSIONTIMEZONE,current_date,LOCALTIMESTAMP,SYSTIMESTAMP FROM dual;
commit;
END nested_loop_b;
/
--
SYS_DATE CURR_TIMESTAMP SESS_TIMEZONE CURR_DATE LOCAL_TIMESTAMP SYS_TIMESTAMP
------------------- --------------------------------------------------------------------------- ------------------------------ ------------------------------ ------------------------------ --------------------------------------------------
2014-02-21 12:03:01 21-FEB-14 12.03.01.035054 PM +08:00 +08:00 2014-02-21 12:03:01 21-FEB-14 12.03.01.035054 PM 21-FEB-14 12.03.01.035051 PM +08:00
2014-02-21 12:06:01 21-FEB-14 12.06.01.108673 PM +08:00 +08:00 2014-02-21 12:06:01 21-FEB-14 12.06.01.108673 PM 21-FEB-14 12.06.01.108671 PM +08:00
SQL>
解决方案:
- 在job中的存储过程用systimestamp取时间戳,而不是用current_timestamp
- 或者,在存储过程中先execute immediate 'alter session set time_zone = ''+08:00''';
由 udpwork.com 聚合
|
评论: 0
|
要! 要! 即刻! Now!