oracle多语言环境下to_date时间转换问题
现象:在多语言环境下使用过oracle的同学想必都遇到过这样一个问题,
date_v date;
date_v := to_date('2010/11/16');--或'2010/11/16'
同一个服务器,不同oracle clinet 不一定都行得通。
原因: 不指定转换字符串的情况下,oracle使用既定的格式串进行日期转换操作,执行SELECT * FROM NLS_SESSION_PARAMETERS;察看NLS信息,其中NLS_DATE_FORMAT是当前的格式化日期的格式化字符串。我这里是"DD-MON-RR"(dd代表日rr代表年mon代表月),所以默认的转换变成to_date('2010/11/16','DD-MON-RR').MON在NLS_LANGUAGE为AMERICAN的情况下只识别Nov而不是别11,所以转换失败。
解决: 既然知道问题原因了,解决这个问题有三个方法。
1,更改NLS_LANGUAGE会使NLS_DATE_FORMAT同步为相应的格式。我们这里需要japanese格式。我通过增加环境变量(NLS_LANG=JAPANESE_JAPAN.JA16SJIS)实现。
NLS_DATE_FORMAT变成RR-MM-DD了,测试,select to_date('2010/11/15') from dual--ok。
2,增加环境变量NLS_DATE_FORMAT(RR-MM-DD或yy-mm-dd或yy/mm/dd任何你需要的格式)。
测试,select to_date('2010/11/15') from dual--ok。
这里要注意经过我测试,rr和yy是一个意思 ,连接符号-和/都可以使转换成功。
更改NLS_LANGUAGE或NLS_DATE_FORMAT的方法可以google以下.
到这里基本大功告成了,但是你也许会说我们不能随便修改oracle client的这些配置,因为其他实例也许需要它!下面是第三个方法
3,to_date有个重载方法,提供转换需要的format。
无论NLS_DATE_FORMAT是什么,select to_date('2010/11/15','yy/mm/dd') from dual--ok。
但是还是不要高兴过早了,select to_date('2010/nov/15','yy/mon/dd') from dual--不一定ok。
当NLS_LANGUAGE环境为AMERICAN时是OK的,为East Asia language时mon格式符真正识别的是11月(这里japan和china还是不一样的,看起来是一个字,但是从我机器输入select to_date('2010/11月/15','yy/mon/dd') from dual却出错。
具体细节可以参考文章http://www.eygle.com/special/NLS_CHARACTER_SET_05.htm
现在问题明白了,但解决方法这么多,难道转换一个字符串到日期真的这么周折?
我选择第三个方法,因为它是我能控制的。select to_date('2010/11/15','yy/mm/dd') from dual--ok,因为mm的转译永远是阿拉伯数字啊。
4, As a SQL function parameter. NLS parameters can be used explicitly to hardcode NLS behavior within a SQL function. Doing so will override the defaults set for the session in the initialization file, the client with environment variables, or set for the session by ALTER SESSION. For example:
TO_CHAR('Mar 24 2011','MM dd yyyy', 'nls_date_language = AMERICAN')
5,As initialization parameters on the server. You can include parameters in the initialization parameter file to specify a default session NLS environment. These settings have no effect on the client side; they control only the server's behavior. For example:
NLS_TERRITORY = "CZECH REPUBLIC"
6,As ALTER SESSION parameters. NLS parameters set in an ALTER SESSION statement can be used to override the defaults set for the session in the initialization file, or set by the client with environment variables.
SQL> ALTER SESSION SET NLS_SORT = FRENCH;
又增加了几个方法,最近在用sqlldr导从sybase出的一个csv时碰到问题,一列时间是 Mar 28 2011这样的,通过分析如果想导入到date列中只有在control文件的列配置中设置成这样 :
, record_date CHAR "to_date(:record_date,'MM dd yyyy','NLS_DATE_LANGUAGE=AMERICAN')"
。。。
最终导入成功,原理说白了就是“tell to SQLLOADER that I need to change his session”。
这个链接里有oracle关于nls方面的知识:http://download.oracle.com/docs/cd/A87860_01/doc/server.817/a76966/ch2.htm#91066
这里有些关于sqlldr load文件的高级资料 :http://www.cnblogs.com/wzc998/archive/2011/03/24/1994137.html
案例:这样一个情景,现在有个存储要部署在未知地理未知服务器上,它需要一个date参数,plsql程序员想当然的吧它定义成了date,不巧,调用存储的另一个程序员是个想通过脚本来调用存储,并且通过windows计划任务触发脚本执行,这个脚本给了一个2010/11/15,看起来没任何问题,但是不巧这台应用服务器的oracle客户端的NLS_LANGUAGE=AMERICAN,真是无巧不成书啊,当oracle做这样一个调用前的参数转换工作的时候 date_v date; date_v := '2010/11/16'(这个转换是默认的不可控的);灾难来临了。
怎么避免这样的灾难呢?参数改成nvarchar吧,自己做参数转换,使用上面我们的第三个解决方法data_v:= to_date(data_vchar,'yy/mm/dd'),其实灾难可以避免。
有人会说,调用存储的人传了个2010¥/11……/16!怎么办,你的yyyy/mm/dd如何处理?当然没法处理,我的方法是给出一个准确的文档告诉对方参数应该是什么格式的,出错了也可以排除责任了。 另外我自己转换可以添加一些异常机制来提示问题,oracle自动转换出错了可是很霸道的。
NLS是什么,可以看这里http://www.cnblogs.com/wzc998/archive/2010/11/17/1879652.html
oracle多语言环境下to_date时间转换问题的更多相关文章
- Oracle 11g RAC环境下Private IP修改方法及异常处理
Oracle 11g RAC环境下Private IP修改方法及异常处理 Oracle 11g RAC环境下Private IP修改方法及异常处理 一. 修改方法 1. 确认所有节点CRS服务以启动 ...
- linux环境下deb格式 转换成rpm格式
linux环境下deb格式 转换成rpm格式 使用alien工具转换deb格式到rpm格式 alien_8.87.tar.gz 下载alien_8.87.tar.gz [root@mysqlnode2 ...
- Dynamics CRM2015 非基础语言环境下产品无法新建的问题
该现象出现在2015版本上,之前从没注意过这个问题不知道以前的版本是否存在. 我的安装包的基础语言是中文,第一张图有添加产品的按钮,切换到英文环境下后就没有了,一开始以为是系统做了隐藏处理,但用工具查 ...
- Oracle 修改语言环境
Oracle数据库还是用英文的比较好,毕竟是外国人开发的.而且许多提示都是模板化 的,所以不懂英文,也不要怕,多Google就会了. 唉,安装Oracle 数据库时,手贱语言选择了中文和英语.结果使用 ...
- Oracle在中文环境下出现乱码解决办法
zysong.ttf下载是一款oracle字体乱码解决工具,实质于缺乏中文字体包! 01情况的例子 02情况的例子 01.在开始安装的时候出现乱码 下载zysong.ttf,unzip 解压 一 ...
- Oracle在不同的语言环境结果to_date错误的问题
我写了一个存储过程,它使用了功能,有一些功能to_date(dateFrom, 'yyyy/mm/dd').执行发现数据插入错误后,数据插入"0001/9/14". 感觉莫名其妙, ...
- linux环境下的时间编程
Linux下提供了丰富的api以供开发者们处理和时间相关的问题.然而这些接口看似各自为政实则有有着千丝万缕的联系,在学习和时间中引发了各种各样的混乱.因此时间处理成为了许多Linux开发者的梦魇,遇到 ...
- 在C语言环境下使用google protobuf
本文写给经常使用C编程且不喜欢C++而又要经常使用google protobuf的人. 经常写通讯程序的人对数据进行序列化或者反序列化时,可能经常使用google的protobuf(PB ...
- springMVC-MyBatis-Mysql 环境下, 返回时间格式不是指定格式
在数据库中的时间是: 比如: 2018-04-06:12;23:34. 但是mybatis查询出来以后是下面的格式. {"updatedTime":{"date" ...
随机推荐
- Perfect Service UVA - 1218
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #inclu ...
- java核心技术卷一
java核心技术卷一 java基础类型 整型 数据类型 字节数 取值范围 int 4 +_2^4*8-1 short 2 +_2^2*8-1 long 8 +_2^8*8-1 byte 1 -128- ...
- codevs——1081 线段树练习 2
1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Description 给你N个数,有两种操作 1:给 ...
- ZOJ3953 ZJU2017校赛(贪心)
题意:给出n个区间,求至少删掉多少个区间使得不存在区间a, b, c 两两相交 (定义两个区间相交是,区间[l1, r1]和区间[l2, r2]相交,当且仅当存在一个数x,l1<=x< ...
- idea中javaweb的mysql8.0.15配置问题
mysql8.0.x以后的版本在连接数据库的时候有些不同. 首先: Class.forName("com.mysql.cj.jdbc.Driver"); 其次: DriverMan ...
- flask到底能登录多少用户?
flask默认情况下是单进程的,所以每次只能处理一个请求: 当然可以多起几个进程或者线程,这样flask就可以处理多个请求: 认证后的用户,进行一次操作(一个GET操作.一次POST操作或者其他),会 ...
- Network problem solving flow chart
来自为知笔记(Wiz)
- Swift 函数Count,Filter,Map,Reduce
原创Blog,转载请注明出处 blog.csdn.net/hello_hwc 前言:和OC不同,Swift有非常多全局的函数,这些全局函数对简化代码来说非常实用.眼下Swift出到了2.0,只是我这篇 ...
- Office 连供打印机无法进纸怎么办 卡纸,塞纸怎么办
我昨天打印还好好的,今天无法进纸了,哪怕只放一张纸,也是左边进去一点点,然后就塞住了,吸不下去了. 因为你的打印机里面有异物.你把连供拆掉(当心墨水流出来,把墨盒拆掉之后放高一点并用纸巾包住,不要 ...
- onenstack 简介
一.云计算的前世今生 所有的新事物都不是突然冒出来的,都有前世和今生.云计算也是IT技术不断发展的产物. 要理解云计算,需要对IT系统架构的发展过程有所认识. 请看下 IT系统架构的发展到目前为止大致 ...