`
school104
  • 浏览: 73297 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Oracle的时区

 
阅读更多
Oracle 9i 开始多了 3 个关于时间的数据类型:TIMESTAMP [(precision)] TIMESTAMP [(precision)] WITH TIME ZONE TIMESTAMP [(precision)] WITH LOCAL TIME ZONE,其中 TIMESTAMP [(precision)] WITH TIME ZONE 保存了时区信息。

1. Oracle 的时区设置

    Oracle 的时区可以分为两种,一种是数据库的时区,一种是 session 时区,也就是客户端连接时的时区(经过实验,连接以后再修改客户端的时区,session 的时区不会更改)。

    数据库的时区在创建数据库时可以通过在 create database 语句中加上 SET TIME_ZONE = ' { { + | - } hh : mi | time_zone_region } ' 来指定,如果,不指定,默认是按照数据库所在的操作系统时区来设定的。创建之后,可以通过 alter database 来修改。其中 time_zone_region 参数可以通过查询 V$TIMEZONE_NAMES 动态视图来获得所有支持的值。修改之后,需要重启数据库才能生效。经常有人会碰到无法修改的情况:

SQL> alter database set time_zone='+06:00';
alter database set time_zone='+06:00'
*
ERROR at line 1:
ORA-02231: missing or invalid option to ALTER DATABASE

    TOM 对此问题有过解释,TIME_ZONE 的设定主要是为了 WITH LOCAL TIME ZONE,当 session 的时区和数据库的时区不同时,oracle 根据时区的差距转换到数据库的时间,再保存到数据库的 WITH LOCAL TIME ZONE 类型中,他是不保存时区的,所以需要 TIME_ZONE 来进行各种时区之间时间的转换(WITH TIME ZONE 类型保存了原始的时区,所以不需要 TIME_ZONE 的设置也可以进行各种时区之间的转换)。但数据库中一旦有了该类型,就不能通过 alter database 修改时区了,会得到上面的错误,可以通过下面的语句获得所有包含该类型的表,将他们删除之后,再修改。

select u.name || '.' || o.name || '.' || c.name TSLTZcolumn
  from sys.obj$ o, sys.col$ c, sys.user$ u
where c.type# = 231
   and o.obj# = c.obj#
   and u.user# = o.owner#;
(一般查询后的结果为:OE.ORDERS.ORDER_DATE,指的是OE用户下的ORDERS表的ORDER_DATE字段使用了时区的信息:WITH LOCAL TIME ZONE,将此信息去掉就可以再修改了,修改好了之后需要重启数据库才能生效)

    Session 的时区是根据客户端的时区来决定的,当然连接以后也可以通过 alter session 来改变。WITH LOCAL TIME ZONE 类型会根据 TIME_ZONE 的设置,自动把时间转换为 session 所在时区的时间显示出来,而 WITH TIME ZONE 因为保存了时区,不需要根据 TIME_ZONE 的设置来转换。

2. 查看时区

    可以分别使用 SESSIONTIMEZONE / DBTIMEZONE 内建函数查看 session 和数据库时区:


SYS@SKYDB> select dbtimezone from dual;

DBTIME
------
+08:00

SYS@SKYDB> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------
+09:00


    另外可以用 TZ_OFFSET 查询某时区和 UTC 之间的差值。


TZ_OFFSET ( { 'time_zone_name'
                        | '{ + | - } hh : mi'
                        | SESSIONTIMEZONE
                        | DBTMEZONE  }
                      )

SELECT TZ_OFFSET('US/Eastern') FROM DUAL;

TZ_OFFS
-------
-04:00

SELECT TZ_OFFSET(DBTIMEZONE) FROM DUAL;

TZ_OFFSET(DBTI
--------------
+08:00

    其中 time_zone_name 也可以从 V$TIMEZONE_NAMES 获得。

3. 几个内建时间函数的比较

    sysdate/systimestamp 都是返回数据库的时间并且使用数据库的时区,他们返回的是操作系统的时间。sysdate 返回的是 date 类型,没有时区信息,操作系统上是什么时间就返回什么时间;systimestamp 返回 TIMESTAMP WITH TIME ZONE 类新,有时区信息:


SYS@SKYDB> select sysdate from dual;

SYSDATE
-------------------
2006-08-03 10:01:31

SYS@SKYDB> select systimestamp from dual;

SYSTIMESTAMP
-----------------------------------------------
03-AUG-06 10.02.21.093000 AM +08:00

SYS@SKYDB> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

修改操作系统时区为 +02:00

SYS@SKYDB> startup
ORACLE instance started.

Total System Global Area   89202456 bytes
Fixed Size                   454424 bytes
Variable Size              62914560 bytes
Database Buffers           25165824 bytes
Redo Buffers                 667648 bytes
Database mounted.
Database opened.

SYS@SKYDB> select sysdate from dual;

SYSDATE
-------------------
2006-08-03 04:03:37

SYS@SKYDB> select systimestamp from dual;

SYSTIMESTAMP
----------------------------------------------
03-AUG-06 04.04.15.687000 AM +02:00
    注:这是我单位机子上实验的结果,由于建了多个数据库,不知道为什么不能通过 ipc 来连接本地数据了,登陆时使用 sqlplus "/@skydb as sysdba",也就是使用了监听器来连接,但在家里做相同的实验,通过 ipc 连接 sqlplus "/as sysdba",修改时区后,sysdate 依然显示修改前的时间,而 systimestamp 却正确,不知道是什么原因:

SQL> select sysdate from dual;

SYSDATE
-------------------
2006-02-08 22:21:40

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
02-AUG-06 10.22.38.578000 PM +08:00

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
修改时区为 +09:00
SQL> startup
ORACLE instance started.

Total System Global Area  131145064
bytes

Fixed Size                   453992
bytes

Variable Size             109051904
bytes

Database Buffers           20971520
bytes

Redo Buffers                 667648

bytes

Database mounted.
Database opened.
SQL> select sysdate from dual;

SYSDATE
---------
02-AUG-06

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

Session altered.

SQL> select sysdate from dual;

SYSDATE
-------------------
2006-08-02 22:32:59              <- 还是之前的时间

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
02-AUG-06 11.35.05.171000 PM +09:00          <- 时间正确

    另外,有个初始化参数 fixed_date,可以设置 sysdate 返回指定的时间:


alter system set fixed_date='2005-04-04-11-00-00'

this fixed_date is normally used, in oracle, for dubugging purpose.

once finishing it, you can set it back:

alter system set fixed_date=none

    Eygle 的关于这个参数的相关文章:Why sysdate is fixed

    current_timestamp/current_date 也会返回数据库的时间,但转换为 session 的时区进行显示,可以使用 alter session set time_zone 改变 session 时区。

4. 四个日期时间类型的实验

SQL> select dbtimezone from dual;

DBTIME
------
+06:00

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
+08:00

SQL> ed
Wrote file afiedt.buf

  1  create table tztest(a date,
  2  b timestamp(0),
  3  c timestamp(0) with time zone,
  4* d timestamp(0) with local time zone)
SQL> /

Table created.

SQL> alter session set nls_date_format ='yyyy-dd-mm hh24:mi:ss';

Session altered.

SQL> select sysdate from dual;

SYSDATE
-------------------
2006-02-08 22:21:40

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
02-AUG-06 10.22.38.578000 PM +08:00

SQL> select current_date from dual;

CURRENT_DATE
-------------------
2006-02-08 22:23:50

SQL> select current_timestamp from dual;

CURRENT_TIMESTAMP
---------------------------------------------------------------------------
02-AUG-06 10.24.04.031000 PM +08:00

SQL> insert into tztest
  2  values(sysdate,systimestamp,systimestamp,systimestamp);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from tztest;

A
-------------------
B
---------------------------------------------------------------------------
C
---------------------------------------------------------------------------
D
---------------------------------------------------------------------------
2006-02-08 22:25:59
02-AUG-06 10.25.59 PM
02-AUG-06 10.25.59 PM +08:00
02-AUG-06 10.25.59 PM

SQL> exit
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production

修改了客户端操作系统的时区

C:\Documents and Settings\Administrator>sqlplus sky/xxxx

SQL*Plus: Release 9.2.0.3.0 - Production on Wed Aug 2 23:28:01 2006

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

Session altered.

SQL> select sysdate from dual;

SYSDATE
-------------------
2006-08-02 22:28:49        <-数据库没有重启,时间依然是修改前的

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
02-AUG-06 11.29.33.609000 PM +09:00  <- 这里却已经改变了,有时区信息,自动转换了?

SQL> select * from tztest;

A
-------------------
B
---------------------------------------------------------------------------
C
---------------------------------------------------------------------------
D
---------------------------------------------------------------------------
2006-08-02 22:25:59                       <- 没变
02-AUG-06 10.25.59 PM                  <- 没变
02-AUG-06 10.25.59 PM +08:00      <- 保存时区信息
02-AUG-06 11.25.59 PM                  <-自动转换为 session 的时区
分享到:
评论

相关推荐

    oracle19c,19.0.0时区版本35补丁p31335037_190000_Linux-x86-64.zip

    oracle19.0时区版本35补丁p31335037_190000_Linux-x86-64.zip 注意:此补丁只适用于oracle19.3版本用来添加35版本时区,其他版本使用会报错 我会再上传一个适用于19c所有oracle版本的35版本时区补丁 补丁用于解决ORA...

    oracle19.3时区版本33补丁p28852325_193000DBRU_Linux-x86-64.zip

    注意:此补丁只适用于oracle19.3版本用来添加33版本时区,其他版本使用会报错 我会再上传一个适用于19c所有oracle版本的33版本时区补丁 补丁用于解决ORA-39405 TSTZ版本问题的错误 用于把oracle19.3数据库加TSTZ33...

    oracle19c升级时区版本 32->42,解决数据泵导数据TSTZ报错

    在Oracle数据库环境中,时区版本的更新是至关重要的,尤其是当你需要处理跨越多个时区的数据或者与不同地区进行数据交换时。"Oracle19c升级时区版本 32-&gt;42,解决数据泵导数据TSTZ报错"这个话题涉及到Oracle数据库中...

    p29997937_190000__oracle34时区全系统版本

    适用于19c所有oracle版本的34版本时区补丁 补丁用于解决ORA-39405 TSTZ版本问题的错误 用于把oracle19c数据库加TSTZ34版本的补丁 可 通过SQL&gt; SELECT * FROM v$timezone_file;命令查询时区版本 打补丁参考...

    ORA-39405-时区版本36全补丁包

    本文将深入探讨“ORA-39405-时区版本36全补丁包”这一主题,主要关注Oracle 19c数据库的时区更新以及相关的文件信息。 首先,"ORA-39405"是一个特定的Oracle错误代码,它通常与数据库的时区设置或更新有关。在...

    oracle19c所有版本通用时区版本34补丁p29997937_190000_Linux-x86-64_34版本.zip

    适用于19c所有oracle版本的34版本时区补丁 补丁用于解决ORA-39405 TSTZ版本问题的错误 用于把oracle19c数据库加TSTZ34版本的补丁 可通过SQL&gt; SELECT * FROM v$timezone_file;命令查询时区版本 安装过程可以查看我的...

    oracle错误及解决方法

    Oracle数据库是全球广泛使用的大型关系型数据库管理系统,其在企业级应用中占据着重要的地位。然而,使用过程中难免会遇到各种错误,这些错误通常以ORA开头的错误代码形式出现。本篇文章将深入探讨Oracle错误及其...

    oracle19c TZ41补丁 p35099667-190000-MSWIN-x86-64.zip

    TZ41补丁可能包含对Oracle数据库时区数据库的更新,这是一份包含了全球所有地区时区信息的庞大数据库,包括夏令时规则等复杂信息。 Oracle 19c是Oracle数据库的一个主要版本,它提供了许多新特性,如增强的性能、...

    oracle19c所有版本通用时区版本33补丁p28852325_190000_Linux-x86-64_33版本.zip

    适用于19c所有oracle版本的33版本时区补丁 补丁用于解决ORA-39405 TSTZ版本问题的错误 用于把oracle19.3数据库加TSTZ33版本的补丁 可通过SQL&gt; SELECT * FROM v$timezone_file;命令查询时区版本 安装过程可以查看我的...

    Virtualbox安装Oracle 19c 升级到19.8(Oracle Restart和数据库)完整步骤

    这个文档是来自鼎甲科技的姚远工作中整理的,在Virtualbox上安装Oracle 19.3 再升级到19.8(Oracle Restart和数据库)完整步骤,包括:配置系统环境,安装grid,oracle,建库,补丁下载升级等全过程。

    oracle安装完成后控制台异常java.lang.exceptionexceptioninsendingrequestnull.docx

    总之,解决“java.lang.Exception: Exception in sendingRequest :: null”异常需要从检查Oracle时区配置、操作系统时区设置以及可能的EM DBControl重建等多个角度出发。通过上述步骤,你应该能够修复控制台的异常并...

    如何在Oracle 9i中正确转换时区

    在Oracle 9i数据库系统中,处理时区转换是一个重要的任务,特别是在全球化的环境中,不同地区的数据交流需要准确地处理时间信息。Oracle 9i引入了一些新的特性来增强时区管理,以解决在早期版本中遇到的问题。在...

    调整数据库时区版本脚本DBMS_DST_scriptsV1.9.zip

    通过此版本可以把oracle时区版本调整到为最新版本,一般配合时区补丁使用 可以参考https://blog.csdn.net/weixin_43885834/article/details/105745901 https://download.csdn.net/download/weixin_43885834/12360971...

    通过JDBC连接Oracle数据库的十大技巧

    选择合适的驱动程序、关闭自动提交、使用PreparedStatement对象、批量处理、调用存储过程以及优化连接池等策略,都是提高Java应用程序与Oracle数据库交互性能的有效手段。同时,定期对系统进行性能监控和调优,是...

    oracle删除和重建实例

    3. 配置实例参数:配置实例参数,包括字符集、国家语言、时区等。 4. 创建实例:使用 dbca 工具或手动创建实例,需要输入管理员密码和其他信息。 注意事项 删除和重建 Oracle 实例需要注意以下几点: * 在删除...

    Oracle UCM连接oracle数据库.doc

    5. 设置资料档案库的位置、管理服务器配置、浏览器路径、语言、时区、服务端口、地址过滤器、URL前缀、邮件服务器、管理员邮件地址、实例标签和说明。 6. 选择Web服务器(这里选择了Microsoft IIS)和安全集成,使用...

    Oracle\oracle_EM无法正常登陆解决方案

    此错误通常是由于Oracle EM 的时区设置不当导致的。 #### 解决方案 1. **设置正确的时区** - 打开Oracle安装目录下的文件`%ORACLE_HOME%\pc-name_sid\sysman\config\emd.properties` (对于Linux系统,路径应为 `...

    Oracle专用Linux操作系统-OracleLinux-R6-U5-Server-x86_64

    Oracle Linux是Oracle公司推出的一款基于Linux内核的操作系统,它主要设计用于支持Oracle数据库、中间件和其他企业级应用。Oracle Linux R6 U5 (Update 5) 是该操作系统的第六个主要版本的第五次更新,提供了对x86_...

    ORACLE19C OPATCH补丁 p6880880-190000-MSWIN-x86-64.zip

    Oracle 19c是Oracle数据库的一个重要版本,它提供了许多增强功能和性能优化。OPatch是Oracle用于安装、管理和更新其产品的工具,特别是在应用补丁时。"OPATCH补丁 p6880880-190000-MSWIN-x86-64.zip"是一个专门针对...

    使用oracle计算系统当前时间的毫秒数

    ### 使用Oracle计算系统当前时间的毫秒数 在IT领域,特别是数据库管理和应用程序开发中,时间戳是非常重要的数据类型之一。它可以用来记录事件的发生时间、处理时间等关键信息。对于Oracle数据库用户而言,有时需要...

Global site tag (gtag.js) - Google Analytics