如何使SQL对所估算的“ RR-MM-DD HH.MI.SSXFF AM”创建的内容更为灵活[22008] [1855] ORA-01855:AM / A.M。或PM / PM需要

时间:2018-07-02 10:34:22

标签: sql oracle

我必须以几种不同的方式输入日期。

  1. to_timestamp('2015-10-06 0:00:00.0 AM', 'RR-MM-DD HH.MI.SSXFF AM')

  1. to_timestamp('2115-10-06 01:00:00.0 AM', 'RR-MM-DD HH.MI.SSXFF AM')

两者的错误

  1. ORA-01849: hour must be between 1 and 12

  2. [22008][1855] ORA-01855: AM/A.M. or PM/P.M. required

我想要实现的是使用2115-10-06 01:00:00.0 AM2015-10-06 0:00:00.0 AM的能力,而不会给我关于'RR-MM-DD HH.MI.SSXFF AM'约束的错误。

1 个答案:

答案 0 :(得分:4)

12小时制的时钟没有0小时。

如果您希望在第12小时内支持第0小时作为别名,则可以编写一个自定义函数以将0替换为12:

SQL Fiddle

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语句:

SQL Fiddle

查询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 |