获取错误 - ORA-01858:找到了数字所在的非数字字符

时间:2015-04-24 16:08:49

标签: oracle

我在下面的sql中收到错误:

  

ORA-01858:找到了一个非数字字符,其中数字是预期的

SELECT   c.contract_num,
         CASE
            WHEN   (  MAX (TO_CHAR (TO_DATE (c.event_dt, 'YYYY-MM-DD'), 'MMDD'))
                    - MIN (TO_CHAR (TO_DATE (c.event_dt, 'YYYY-MM-DD'), 'MMDD')))
                 / COUNT (c.event_occurrence) < 32
            THEN
              'Monthly'
            WHEN       (  MAX (
                            TO_CHAR (TO_DATE (c.event_dt, 'YYYY-MM-DD'), 'MMDD'))
                        - MIN (
                            TO_CHAR (TO_DATE (c.event_dt, 'YYYY-MM-DD'), 'MMDD')))
                     / COUNT (c.event_occurrence) >= 32
                 AND   (  MAX (
                            TO_CHAR (TO_DATE (c.event_dt, 'YYYY-MM-DD'), 'MMDD'))
                        - MIN (
                            TO_CHAR (TO_DATE (c.event_dt, 'YYYY-MM-DD'), 'MMDD')))
                     / COUNT (c.event_occurrence) < 91
            THEN
              'Quarterley'
            ELSE
              'Yearly'
         END
FROM     ps_ca_bp_events c
GROUP BY c.contract_num;

4 个答案:

答案 0 :(得分:18)

您收到的错误要么是因为您对已经是日期的列进行了TO_DATE,并且您使用的格式掩码与您的{{1}不同参数[1]或因为event_occurrence列包含的数据不是数字。

您需要a)更正您的查询,以便它不在日期列上使用TO_DATE,并且b)更正您的数据,如果event_occurrence应该只是数字。

修复该列的数据类型,以确保只能存储数字。



[1] Oracle做的事情:nls_date_format是: TO_DATE(date_column, non_default_format_mask)

通常,默认TO_DATE(TO_CHAR(date_column, nls_date_format), non_default_format_mask)参数设置为nls_date_format,因此在您的查询中,可能发生的事情是您的日期列转换为dd-格式的字符串星期一,然后您使用MMDD格式将其恢复为日期。该字符串不是这种格式,因此您会收到错误。

答案 1 :(得分:1)

不仅由于日期转换,还会出现此错误

当我们尝试传递日期而预期使用varchar时,可能会出现此错误

当我们尝试传递varchar而预期日期时。

在预期使用varchar时使用to_char(sysdate,'YYYY-MM-DD')

答案 2 :(得分:0)

我添加了TO_DATE并解决了问题。

修改前 - 由于以下条件,我收到此错误

record_update_dt>='05-May-2017'

修改后 - 添加to_date后,问题得到解决。

record_update_dt>=to_date('05-May-2017','DD-Mon-YYYY')

答案 3 :(得分:-1)

您可以通过检查日期是否与REGEX模式匹配来解决问题。如果不是,则为NULL(或您喜欢的其他方式)。

在我的特定情况下,这是有必要的,因为我有20个以上的DATE列另存为CHAR,因此我不知道错误来自哪一列。

返回您的查询:

1。声明一个REGEX模式。
通常它是一个很长的字符串,肯定会污染您的代码(您可能还想重用它)。

Unload objLoop

别忘了在正则表达式中用双引号引起来的单引号:-)

有关Regex日期验证的综合性话题,您会发现here

2。将其用作第一种情况:

要在define REGEX_DATE = "'your regex pattern goes here'"语句中使用正则表达式验证,您不能使用SELECT(仅在REGEXP_LIKE中有效。我花了很长时间来理解为什么我的代码无法正常工作。所以值得一提。

相反,请使用WHERE
对于模式中找不到的条目(您的情况),请使用REGEXP_INSTR

REGEXP_INSTR (variable, pattern) = 0