我在访问日期查询时遇到错误

时间:2017-03-02 11:45:32

标签: java database date oracle-sqldeveloper

我收到此日期查询时出现此错误:

SELECT Y.ITEM_ID
FROM (
    SELECT DISTINCT DOM1.ITEM_ID
        ,COUNT(1)
    FROM (
        SELECT ITEM_ID
            ,COUNT(1)
            ,MAX(ATTRIBUTE_1) ATTRIBUTE_1
        FROM (
            SELECT UNIQUE domain_index.item_id
                ,CASE 
                    WHEN domain_index.ATTRIBUTE_FIELD_ID = 382767
                        THEN DECODE(ATTRIBUTE_VALUE, NULL, '1A2B3C4D5E6F7G8H9I0J0K1L2M3N4O5P6Q7R8S9T0U5V4W3X2Y1Z', ATTRIBUTE_VALUE)
                    END AS ATTRIBUTE_1
            FROM T_DOMAIN_INDEX domain_index
            WHERE DOMAIN_ID = 64279
                AND (
                    ATTRIBUTE_FIELD_ID = 382767
                    AND (to_date('01 ' || nvl(to_char(to_date(replace(TRIM(ATTRIBUTE_VALUE), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'), '01 0001'), 'dd/mm/yyyy') <> to_date('01 Mar 2017', 'dd/mm/yyyy'))
                    )
            )
        GROUP BY item_id
        ) DOM1
    WHERE (to_date('01 ' || nvl(to_char(to_date(replace(TRIM(DOM1.ATTRIBUTE_1), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'), '01 0001'), 'dd/mm/yyyy') <> to_date('01 Mar 2017', 'dd/mm/yyyy'))
        AND (to_date('01 ' || nvl(to_char(to_date(replace(TRIM(DOM1.ATTRIBUTE_1), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'), '01 0001'), 'dd/mm/yyyy') <> to_date('01 01 0001', 'dd/mm/yyyy'))
    GROUP BY DOM1.ITEM_ID
    ) Y
    ,T_DOMAIN_ITEM A
WHERE Y.ITEM_ID = A.ITEM_ID
    AND NVL(A.PARENT_ITEM_ID, 0) = 0
    AND A.IS_ARCHIVED = 0
ORDER BY DT_UPDATED DESC
    ,Y.ITEM_ID
  

错误:ORA-01861:文字与格式字符串不匹配   01861. 00000 - &#34;文字与格式字符串不匹配&#34;   *原因:输入中的文字必须与文字中的文字长度相同              格式字符串(前导空格除外)。如果              &#34; FX&#34;修改器已经切换,文字必须完全匹配,              没有额外的空白。   *操作:更正格式字符串以匹配文字。

属性值可以是ISO格式的日期,也可以为null或空白。当其中一个属性值为空时,会收到此错误。

2 个答案:

答案 0 :(得分:2)

我不是Oracle期待的,而是你的代码

SELECT Y.ITEM_ID
FROM (SELECT DISTINCT
        DOM1.ITEM_ID,
        COUNT(1)
      FROM (SELECT
              ITEM_ID,
              COUNT(1),
              MAX(ATTRIBUTE_1) ATTRIBUTE_1
            FROM (SELECT UNIQUE
                    domain_index.item_id,
                    CASE WHEN domain_index.ATTRIBUTE_FIELD_ID = 382767
                      THEN DECODE(ATTRIBUTE_VALUE, NULL, '1A2B3C4D5E6F7G8H9I0J0K1L2M3N4O5P6Q7R8S9T0U5V4W3X2Y1Z',
                                  ATTRIBUTE_VALUE) END AS ATTRIBUTE_1
                  FROM T_DOMAIN_INDEX domain_index
                  WHERE DOMAIN_ID = 64279 AND (ATTRIBUTE_FIELD_ID = 382767 AND (to_date('01 ' || nvl(
                      to_char(to_date(replace(TRIM(ATTRIBUTE_VALUE), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'),
                      '01 0001'), 'dd/mm/yyyy') <> to_date('01 Mar 2017', 'dd/mm/yyyy'))))
            GROUP BY item_id) DOM1
      WHERE (to_date('01 ' || nvl(
          to_char(to_date(replace(TRIM(DOM1.ATTRIBUTE_1), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'), '01 0001'),
                     'dd/mm/yyyy') <> to_date('01 Mar 2017', 'dd/mm/yyyy')) AND (to_date('01 ' || nvl(
          to_char(to_date(replace(TRIM(DOM1.ATTRIBUTE_1), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'), '01 0001'),
                                                                                         'dd/mm/yyyy') <>
                                                                                 to_date('01 01 0001', 'dd/mm/yyyy'))
      GROUP BY DOM1.ITEM_ID) Y, T_DOMAIN_ITEM A
WHERE Y.ITEM_ID = A.ITEM_ID AND NVL(A.PARENT_ITEM_ID, 0) = 0 AND A.IS_ARCHIVED = 0
ORDER BY DT_UPDATED DESC, Y.ITEM_ID

具有to_date函数,它具有不同的日期值和格式。例如

to_date('01 01 0001', 'dd/mm/yyyy')

你应该替换为

to_date('01/01/0001', 'dd/mm/yyyy')

表达中的任何地方。

答案 1 :(得分:0)

问题源于此:

DECODE(ATTRIBUTE_VALUE, NULL,
 '1A2B3C4D5E6F7G8H9I0J0K1L2M3N4O5P6Q7R8S9T0U5V4W3X2Y1Z', ATTRIBUTE_VALUE)

当您的属性值为null时,您将其替换为该固定字符串,别名为ATTRIBUTE_1。这是在内联视图中别名为DOM1

在下一级别你正在过滤

WHERE (to_date('01 ' || nvl(to_char(to_date(replace(TRIM(DOM1.ATTRIBUTE_1), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'), '01 0001'), 'dd/mm/yyyy') ...

如果您将解码后的值放入您实际执行的位置,或者仅将此部分放入:

to_date('01 ' || nvl(to_char(to_date(replace(TRIM(DOM1.ATTRIBUTE_1), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS')

你真的在做:

select to_date(replace(TRIM('1A2B3C4D5E6F7G8H9I0J0K1L2M3N4O5P6Q7R8S9T0U5V4W3X2Y1Z'), 'T', ' '), 'YYYY-MM-DD HH24:MI:SS') from dual;

并且显然不是有效的ISO(或任何其他)日期格式;因此ORA-01861错误。

不知道你为什么使用那个固定的字符串代替空值,不清楚你是不应该做那个解码,还是应该以不同的方式处理那个值 - 作为where子句中的一个例外也许。这似乎毫无意义,因为除了日期转换之外它没有用于任何东西。

顺便说一下,您似乎在日期之间进行了大量转换,只是为了获得本月的第一天。而不是做类似的事情:

select to_date('01 ' || nvl(to_char(to_date(replace(TRIM('2017-03-02T17:04:30'), 'T', ' '),
  'YYYY-MM-DD HH24:MI:SS'), 'Mon YYYY'), '01 0001'), 'dd/mm/yyyy')
from dual;
你可以这样做:

select nvl(trunc(to_date('2017-03-02T17:04:30', 'YYYY-MM-DD"T"HH24:MI:SS'), 'MM'), 
  date '0001-01-01') from dual;

正如@DmitryGorkovets所指出的那样,您也应该始终如一地使用日期格式掩码,但您也可以使用ANSI日期文字来表示固定日期,例如:而不是to_date('01 Mar 2017', 'dd/mm/yyyy')你可以做date '2017-03-01'