我必须以几种不同的方式输入日期。
to_timestamp('2015-10-06 0:00:00.0 AM', 'RR-MM-DD HH.MI.SSXFF AM')
和
to_timestamp('2115-10-06 01:00:00.0 AM', 'RR-MM-DD HH.MI.SSXFF AM')
两者的错误
ORA-01849: hour must be between 1 and 12
[22008][1855] ORA-01855: AM/A.M. or PM/P.M. required
我想要实现的是使用2115-10-06 01:00:00.0 AM
或2015-10-06 0:00:00.0 AM
的能力,而不会给我关于'RR-MM-DD HH.MI.SSXFF AM'
约束的错误。
答案 0 :(得分:4)
12小时制的时钟没有0小时。
如果您希望在第12小时内支持第0小时作为别名,则可以编写一个自定义函数以将0替换为12:
Oracle 11g R2架构设置:
CREATE FUNCTION parse_timestamp(
in_string VARCHAR2
) RETURN TIMESTAMP
IS
p_string VARCHAR2(30) := in_string;
c_fix_hours CHAR(61) := '^(\d{1,4}-\d\d?-\d\d? )00?(:[0-5]?\d:[0-5]?\d(\.\d+)? [AP]M)$';
BEGIN
IF REGEXP_LIKE( p_string, c_fix_hours, 'i' ) THEN
p_string := REGEXP_REPLACE( p_string, c_fix_hours, '\112\2', 1, 1, 'i' );
END IF;
RETURN TO_TIMESTAMP( p_string, 'RR-MM-DD HH12.MI.SSXFF AM' );
END;
/
查询1 :
SELECT parse_timestamp(
'2015-10-06 0:00:00.0 AM'
),
parse_timestamp(
'2115-10-06 01:00:00.0 AM'
)
FROM DUAL
Results :
| PARSE_TIMESTAMP('2015-10-060:00:00.0AM') | PARSE_TIMESTAMP('2115-10-0601:00:00.0AM') |
|------------------------------------------|-------------------------------------------|
| 2015-10-06 00:00:00.0 | 2115-10-06 01:00:00.0 |
更新使用CASE
语句:
查询1 :
WITH test_data ( value ) AS (
SELECT '2015-10-06 0:00:00.0 AM' FROM DUAL UNION ALL
SELECT '2115-10-06 01:00:00.0 AM' FROM DUAL UNION ALL
SELECT '5-9-7 00:59:59.234 PM' FROM DUAL
)
SELECT TO_TIMESTAMP(
CASE
WHEN REGEXP_LIKE( value, '^(\d{1,4}-\d\d?-\d\d? )00?(:[0-5]?\d:[0-5]?\d(\.\d+)? [AP]M)$', 'i' )
THEN REGEXP_REPLACE( value, '^(\d{1,4}-\d\d?-\d\d? )00?(:[0-5]?\d:[0-5]?\d(\.\d+)? [AP]M)$', '\112\2', 1, 1, 'i' )
ELSE value
END,
'RR-MM-DD HH12.MI.SSXFF AM'
) AS datetime
FROM test_data
Results :
| DATETIME |
|-------------------------|
| 2015-10-06 00:00:00.0 |
| 2115-10-06 01:00:00.0 |
| 2005-09-07 12:59:59.234 |