我想知道是否可以在一列中包含2种格式的日期。
问题是,如果表是NULL,这是一个日期,我需要有一个默认值,如果表是非null,那么我只需要一个时间戳。
我做了一个应该这样做的CASE,但它不起作用。
CASE WHEN s.time IS null
THEN
TO_DATE('01-JAN-1901 01:00:00', 'dd-MON-yyyy HH24:MI:SS')
ELSE
TO_DATE(s.time, 'HH24:MI:SS')
END AS time
该声明给了我“ ORA-01858:找到了一个非数字字符,其中包含数字。”
如果我尝试这样的事情:
CASE WHEN s.time IS null
THEN
TO_DATE('01-JAN-1901 01:00:00', 'dd-MON-yyyy HH24:MI:SS')
ELSE
TO_DATE(TO_CHAR(s.time, 'HH24:MI:SS'), 'HH24:MI:SS')
END AS time
它会起作用,但它会在时间前添加一个日期 - 它看起来像这样: (我不知道从2013年7月1日到哪里获得该日期)
TIME
-------
01-JAN-1901 01:00:00
01-JUL-2013 15:35:00
而不是:
TIME
-------
01-JAN-1901 01:00:00
15:35:00
(这就是我想要的)
答案 0 :(得分:1)
由于它仅用于显示,因此您需要在TO_CHAR()
中使用TO_DATE()
代替ELSE
,但两个分支都必须生成字符串:
CASE WHEN s.time IS null
THEN
TO_CHAR(TO_DATE('01-JAN-1901 01:00:00', 'dd-MON-yyyy HH24:MI:SS'))
ELSE
TO_CHAR(s.time, 'HH24:MI:SS')
END AS time
除非您想依赖TO_CHAR(TO_DATE())
,否则NLS_DATE_FORMAT
是多余的,所以这更简单:
CASE WHEN s.time IS null
THEN
'01-JAN-1901 01:00:00'
ELSE
TO_CHAR(s.time, 'HH24:MI:SS')
END AS time
SQL Fiddle这两种方法。
您从初始版本获得ORA-01858,因为您将DATE
传递给TO_DATE()
。这需要一个字符串参数,这会导致隐式转换,所以你真的在做:
TO_DATE(TO_CHAR(s.time), 'HH24:MI:SS')
根据您的NLS_DATE_FORMAT
设置似乎是:
TO_DATE(TO_CHAR(s.time, 'DD-MON-YYYY HH24:MI:SS'), 'HH24:MI:SS')
所以你最终会尝试做类似的事情:
TO_DATE('16-JUL-2013 15:35:00', 'HH24:MI:SS')
并且您收到错误,因为它会尝试将JUL
(或您的实际数据所具有的任何月份)解释为分钟值的数值,对于格式掩码的MI
部分,您提供。
答案 1 :(得分:0)
您可以使用子字符串并删除日期
CASE WHEN时间为空 然后
TO_DATE('01 -JAN-1901 01:00:00','dd-MON-yyyy HH24:MI:SS')
ELSE SUBSTRING() 结束时间