11

执行此操作时,我有一个字符串列 COL1

SELECT TO_CHAR(TO_DATE(COL1,'dd-mon-yy'), 'mm/dd/yyyy')
FROM TABLE1

COL1 中的数据在 dd-mon-yy 中,例如:27-11-89 和 89 是 1989,但选择将其返回为 11/27/2089。

我必须做一个内部 TO_DATE 因为如果我不这样做,我会收到一个无效号码错误(ORA-01722:无效号码)

如何显示 1989 而不是 2089?请帮忙

4

5 回答 5

30

COL1 中的数据在 dd-mon-yy

不,这不对。列DATE没有任何格式。它仅在您显示它时由您的 SQL 客户端转换(隐式)为该表示形式。

如果 COL1 确实是DATE使用to_date()on 的列,则它是无用的,因为to_date()将字符串转换为 DATE。

你只需要to_char(),没有别的:

SELECT TO_CHAR(col1, 'mm/dd/yyyy') 
FROM TABLE1

在您的情况下发生的情况是调用to_date()将 转换DATE为字符值(应用默认的 NLS 格式),然后将其转换回 DATE。由于这种双重隐式转换,一些信息会在途中丢失。


编辑

因此,您确实犯了将 DATE 存储在字符列中的大错误。这就是你现在遇到问题的原因。

最好的(老实说:唯一明智的)解决方案是将该列转换为DATE. 然后,您可以将值转换为您想要的任何表示形式,而无需担心隐式数据类型转换。

但最有可能的答案是“我继承了这个模型,我必须处理它”(它总是,显然没有人负责选择错误的数据类型),那么你需要使用RR而不是YY

SELECT TO_CHAR(TO_DATE(COL1,'dd-mm-rr'), 'mm/dd/yyyy')
FROM TABLE1

应该做的伎俩。请注意,我也更改monmm您的示例,27-11-89其中包含月份的数字,而不是“单词”(如NOV

有关更多详细信息,请参阅手册:http ://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm#SQLRF00215

于 2012-11-27T19:28:43.857 回答
1

尝试这个。甲骨文有这个功能来区分千年..

正如您所提到的,如果您的列是 varchar,那么下面的查询将为您生成 1989..

从 table1 中选择 to_date(column_name,'dd/mm/rr');

当格式 rr 用于年份时,以下将由 oracle 完成。

如果 rr->00 到 49 ---> 结果将是 2000 - 2049,如果 rr->50 到 99 ---> 结果将是 1950 - 1999

于 2012-11-28T03:56:01.130 回答
0

如果您的列是DATE类型(如您所说),那么您不需要先将其转换为字符串(实际上您会先将其隐式转换为字符串,然后显式转换为日期,然后再显式转换为字符串):

SELECT TO_CHAR(COL1, 'mm/dd/yyyy') FROM TABLE1

您在专栏中看到的日期格式是您使用的工具(TOAD、SQL Developer 等)及其语言设置的产物。

于 2012-11-27T19:29:25.230 回答
0

另一件需要注意的事情是,您正在尝试将日期转换为 mm/dd/yyyy,但如果您有任何计划将此转换后的日期与其他日期进行比较,请确保仅将其转换为 yyyy-mm-dd 格式,因为 to_char 字面意思是将其转换为字符串,并且使用任何其他格式,我们都会得到不希望的结果。有关更多解释,请遵循以下内容: Comparing Dates in Oracle SQL

于 2014-11-16T18:27:06.453 回答
0
SELECT * from 
(SELECT TO_CHAR(COL1, 'yyyy-MM-dd') as col1 FROM TABLE1
) T
WHERE col1 ='2021-11-12'
于 2021-11-12T08:05:07.170 回答