当我这样做时,我有一个字符串列COL1
SELECT TO_CHAR(TO_DATE(COL1,'dd-mon-yy'), 'mm/dd/yyyy')
FROM TABLE1
COL1中的数据是dd-mon-yy,例如:27-11-89和89是1989,但是select将其返回为11/27/2089。
我必须做一个内部的TO_DATE因为如果我没有那么我得到一个无效的数字错误(ORA-01722:无效的数字)
如何显示1989而不是2089?请帮忙
答案 0 :(得分:28)
COL1中的数据位于dd-mon-yy
不,不是。 不 的DATE
列具有任何格式。当您显示它时,它只会被SQL客户端(隐含地)转换为该表示。
如果COL1实际上是使用DATE
的{{1}}列,则无效,因为to_date()
会将字符串转换为DATE。
你只需要to_char(),没有别的:
to_date()
在您的情况下,调用SELECT TO_CHAR(col1, 'mm/dd/yyyy')
FROM TABLE1
将to_date()
转换为字符值(应用默认的NLS格式),然后将其转换回DATE。由于这种双重隐式转换,一些信息在途中丢失了。
修改强>
所以你确实犯了一个大错误,就是把DATE存储在一个字符列中。这就是你现在遇到问题的原因。
最好的(也是诚实的:唯一明智的)解决方案是将该列转换为DATE
。然后,您可以将值转换为您想要的任何重新呈现,而不必担心隐式数据类型转换。
但很可能答案是“我继承了这个模型,我必须应对它”(它总是,显然没有人负责选择错误的数据类型),那么你需要使用DATE
代替RR
:
YY
应该做的伎俩。请注意,我还将SELECT TO_CHAR(TO_DATE(COL1,'dd-mm-rr'), 'mm/dd/yyyy')
FROM TABLE1
更改为mon
,因为您的示例为mm
,其中包含月份编号,而不是“字”(如 NOV )< / p>
有关详细信息,请参阅手册:http://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm#SQLRF00215
答案 1 :(得分:1)
试试这个。甲骨文有这个功能来区分千年......
正如您所提到的,如果您的列是varchar,那么下面的查询将为您提供1989 ..
从table1中选择to_date(column_name,'dd / mm / rr');
当年份使用格式rr时,以下内容将由oracle完成。
如果rr-> 00到49 ---&gt;结果将是2000年至2049年, 如果rr-> 50到99 ---&gt;结果将是1950年至1999年
答案 2 :(得分:0)
如果您的列的类型为 DATE (如您所说),那么您不需要先将其转换为字符串(实际上您会先将其隐式转换为字符串,然后显式地显示日期并再次显式地显示为字符串):
SELECT TO_CHAR(COL1, 'mm/dd/yyyy') FROM TABLE1
您对列所见的日期格式是您使用的工具(TOAD,SQL Developer等)及其语言设置的工件。
答案 3 :(得分:0)
另一件需要注意的事情是你试图以mm / dd / yyyy转换日期,但如果你有任何计划将这个转换日期与其他日期进行比较,那么请确保仅以yyyy-mm-dd格式转换它因为to_char字面上将它转换为字符串,并且使用任何其他格式,我们将得到不希望的结果。 如有更多解释,请按照以下步 Comparing Dates in Oracle SQL