【问题标题】:ORA-01861: literal does not match format string for case statement in oracleORA-01861: 文字与 oracle 中 case 语句的格式字符串不匹配
【发布时间】:2018-09-07 08:03:08
【问题描述】:

请帮我纠正这个错误,我不断收到这个错误

ORA-01861: 文字与 case 语句的格式字符串不匹配 神谕

SELECT activity_made,
       (CASE
            WHEN (TO_DATE(activity_made, 'DD-Mon-YYYY')) = TRUNC(SYSDATE) THEN TO_CHAR(activity_made, 'hh12:mi PM')
            WHEN TRUNC(TO_DATE(activity_made, 'MM-DD-YYYY')) BETWEEN TRUNC(SYSDATE, 'yy') AND TRUNC(SYSDATE - 1) THEN TO_CHAR(activity_made, 'Mon dd')
            ELSE TO_CHAR(TO_DATE(activity_made, 'MM/DD/YYYY'), 'mm/dd/yyyy')
        END)
           AS actmode
  FROM (SELECT (CASE
                    WHEN (SELECT COUNT(*)
                            FROM sfa_activity sa
                           WHERE     sa.companyid = opp.companyid
                                 AND sa.opptyid = opp.opptyid
                                 AND sa.TYPE = 'NOTE') > 0
                    THEN
                        (SELECT NVL(MAX(TO_CHAR(sa.updat, 'YYYY/MM/DD HH24:MI:SS')), '0000/00/00 00:00:00')
                           FROM sfa_activity sa
                          WHERE     sa.companyid = opp.companyid
                                AND sa.opptyid = opp.opptyid
                                AND sa.TYPE = 'NOTE')
                    ELSE
                        (SELECT NVL(MAX(TO_CHAR(sa.updat, 'YYYY/MM/DD HH24:MI:SS')), '1001/01/01 01:01:01')
                           /*ELSE (SELECT (MAX(TO_CHAR(sa.updat,'YYYY/MM/DD HH24:MI:SS')))*/
                           FROM sfa_activity sa
                          WHERE     sa.companyid = opp.companyid
                                AND sa.opptyid = opp.opptyid
                                AND sa.TYPE <> 'NOTE')
                END)
                   AS activity_made
          FROM sfa_opportunities opp
         WHERE companyid = 1192)

【问题讨论】:

  • 0000/00/00 00:00:00 不是有效日期,您无法将其转换为 DATE 值。使用TO_CHARTO_DATE 函数来乱转看起来很奇怪。最好使用 DATE 值运行所有逻辑,并在最后只设置一次输出格式。
  • 为什么将日期存储在VARCHAR 列中?这是一个非常糟糕的主意

标签: oracle date datetime


【解决方案1】:

似乎ACTIVITY_MADEyyyy/mm/dd hh24:mi:ss 格式(如内联视图所建议的那样)。如果简化,您的查询看起来像

select to_date(activity_made, ...) --> should use the same format as below, in an inline view
from (select activity_made         -->TO_CHAR(sa.updat, 'YYYY/MM/DD HH24:MI:SS')
      from sfa_opportunities) 

所以:如果您为activity_made 使用了该格式掩码,您应该在main SELECT 中将它用于TO_CHAR。但是,您使用了

  • dd-mon-yyyy
  • mm-dd-yyyy
  • mm/dd/yyyy

CASE 中切换到yyyy/mm/dd hh24:mi:ss

【讨论】:

    【解决方案2】:

    我建议您将查询重写为以下内容:

    SELECT sa.updat activity_made
         , CASE WHEN TRUNC(sa.updat) = TRUNC(SYSDATE) THEN TO_CHAR(sa.updat, 'hh12:mi PM')
                WHEN sa.updat > TRUNC(SYSDATE,'yy') THEN TO_CHAR(sa.updat, 'Mon dd')
                ELSE TO_CHAR(sa.updat, 'mm/dd/yyyy')
           END actmode
      FROM sfa_activity sa
     WHERE (sa.companyid, sa.opptyid) IN (SELECT opp.companyid, opp.opptyid 
                                            FROM sfa_opportunities opp
                                           WHERE companyid = 1192)
     ORDER BY CASE WHEN sa.TYPE = 'NOTE' THEN 0 ELSE 1 END, sa.updat DESC
     FETCH first ROW ONLY 
    

    你的版本有一些缺点:

    • 不必要的类型转换
    • 同一张表上的很多选择,这是不需要的
    • 可能还有一些性能问题

    没有进行活动时的处理应该在外部而不是在内部选择中进行。 (使其更易于维护。)

    【讨论】:

      【解决方案3】:

      谢谢大家,我通过在activity_made中应用案例得到了解决方案

      /* Formatted on 2018/09/10 14:15 (Formatter Plus v4.8.5) */
      SELECT activity_made,
             (CASE
                 WHEN activity_made = '0000/00/00 00:00:00'
                    THEN NULL
                 ELSE activity_made
              END
             ) AS actmode
        FROM (SELECT (CASE
                         WHEN (SELECT COUNT (*)
                                 FROM sfa_activity sa
                                WHERE sa.companyid = opp.companyid
                                  AND sa.opptyid = opp.opptyid
                                  AND sa.TYPE = 'NOTE') > 0
                            THEN (SELECT NVL
                                            (MAX
                                                (TO_CHAR
                                                    (CASE
                                                        WHEN TRUNC (sa.updat) =
                                                                     TRUNC (SYSDATE)
                                                           THEN TO_CHAR
                                                                       (sa.updat,
                                                                        'hh12:mi PM'
                                                                       )
                                                        WHEN TRUNC (sa.updat)
                                                               BETWEEN TRUNC
                                                                           (SYSDATE,
                                                                            'yy'
                                                                           )
                                                                   AND TRUNC
                                                                          (  SYSDATE
                                                                           - 1
                                                                          )
                                                           THEN TO_CHAR (sa.updat,
                                                                         'Mon dd'
                                                                        )
                                                        ELSE TO_CHAR (sa.updat,
                                                                      'DD/MM/YYYY'
                                                                     )
                                                     END
                                                    )
                                                ),
                                             '0000/00/00 00:00:00'
                                            )
                                    FROM sfa_activity sa
                                   WHERE sa.companyid = opp.companyid
                                     AND sa.opptyid = opp.opptyid
                                     AND sa.TYPE = 'NOTE')
                         ELSE (SELECT NVL
                                         (MAX
                                             (TO_CHAR
                                                 (CASE
                                                     WHEN TRUNC (sa.updat) =
                                                                     TRUNC (SYSDATE)
                                                        THEN TO_CHAR (sa.updat,
                                                                      'hh12:mi PM'
                                                                     )
                                                     WHEN TRUNC (sa.updat)
                                                            BETWEEN TRUNC (SYSDATE,
                                                                           'yy'
                                                                          )
                                                                AND TRUNC (  SYSDATE
                                                                           - 1
                                                                          )
                                                        THEN TO_CHAR (sa.updat,
                                                                      'Mon dd'
                                                                     )
                                                     ELSE TO_CHAR (sa.updat,
                                                                   'DD/MM/YYYY'
                                                                  )
                                                  END
                                                 )
                                             ),
                                          '0000/00/00 00:00:00'
                                         )
                                 /*ELSE (SELECT (MAX(TO_CHAR(sa.updat,'YYYY/MM/DD HH24:MI:SS')))*/
                               FROM   sfa_activity sa
                                WHERE sa.companyid = opp.companyid
                                  AND sa.opptyid = opp.opptyid
                                  AND sa.TYPE <> 'NOTE')
                      END
                     ) AS activity_made
                FROM sfa_opportunities opp
               WHERE companyid = 1192)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-24
        • 2015-01-11
        • 2010-11-26
        • 2012-10-09
        • 2014-04-27
        相关资源
        最近更新 更多