Oracle 获取错误-ORA-01858:在需要数字的位置找到非数字字符

Oracle 获取错误-ORA-01858:在需要数字的位置找到非数字字符,oracle,Oracle,我在下面的sql中得到错误: ORA-01858:在需要数字的位置找到非数字字符 选择c.contract\u num, 案例 当(最大值(到字符(到日期(c.event'dt,'yyyyy-MM-DD'),'MMDD')) -最小值(至字符(至日期(c.事件日期,'YYYY-MM-DD'),'MMDD')) /计数(c.事件发生次数)=32 和(最大值)( TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD')) -闵( TO_CHAR(TO_DAT

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

ORA-01858:在需要数字的位置找到非数字字符

选择c.contract\u num,
案例
当(最大值(到字符(到日期(c.event'dt,'yyyyy-MM-DD'),'MMDD'))
-最小值(至字符(至日期(c.事件日期,'YYYY-MM-DD'),'MMDD'))
/计数(c.事件发生次数)<32
然后
“每月”
何时(最大值)(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
-闵(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
/计数(c.事件发生次数)>=32
和(最大值)(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
-闵(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
/计数(c.事件发生次数)<91
然后
“夸特利”
其他的
“每年”
结束
来自ps_ca_bp_事件c
按合同编号分组;

您遇到的错误可能是因为您对已经是日期的列执行了
TO_DATE
,并且您使用的格式掩码与
nls_DATE_format
参数[1]不同,也可能是因为事件发生列包含的数据不是数字

您需要a)更正查询,使其不用于在“日期”列中指定日期,以及b)更正数据(如果事件的发生应该只是数字)

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



[1] Oracle在执行以下操作时所做的:
TO\u DATE(日期列,非默认格式\u掩码)
是:
TO\u日期(TO\u字符(日期列,nls\u日期格式),非默认格式\u掩码)

通常,默认的
nls_date_format
参数设置为
dd MON yy
,因此在查询中,可能发生的情况是将日期列转换为dd MON yy格式的字符串,然后使用MMDD格式将其返回到日期。字符串不是此格式,因此您会收到一个错误。

我在日期中添加了
,解决了这个问题

修改前-由于以下情况,我得到了此错误

record_update_dt>='05-May-2017'
修改后-将
添加到日期后
,问题得到解决

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

此错误可能不仅是因为日期转换

当我们试图传递日期时可能会出现此错误,而varchar是预期的

当我们试图传递varchar时,而日期是预期的


使用to_char(sysdate,'YYYY-MM-DD')当需要varchar时

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

在我的特殊情况下,这是必要的,因为我有>20个日期列保存为CHAR,所以我不知道错误来自哪个列

返回您的查询:

1。声明正则表达式模式。
它通常是一个很长的字符串,这肯定会污染您的代码(您可能也希望重用它)

不要忘记在正则表达式的双引号中加上一个单引号:-)

一个关于Regex日期验证的综合性线程

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

要在
SELECT
语句中使用正则表达式验证,您不能像
一样使用
REGEXP\u
(它只在
WHERE
中有效。我花了很长时间才明白我的代码为什么不起作用。因此,这当然值得注意

相反,请使用
REGEXP\u INSTR

对于在模式(您的案例)中未找到的条目,请使用
REGEXP\u INSTR(变量,模式)=0

    DEFINE REGEX_DATE = "'your regex pattern goes here'"

    SELECT   c.contract_num,
         CASE
            WHEN REGEXP_INSTR(c.event_dt, &REGEX_DATE) = 0 THEN NULL
            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;
DEFINE REGEX_DATE=“'your REGEX pattern goes here'”
选择c.contract\u num,
案例
当REGEXP_INSTR(c.event_dt,®EX_DATE)=0时,则为空
当(最大值(到字符(到日期(c.event'dt,'yyyyy-MM-DD'),'MMDD'))
-最小值(至字符(至日期(c.事件日期,'YYYY-MM-DD'),'MMDD'))
/计数(c.事件发生次数)<32
然后
“每月”
何时(最大值)(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
-闵(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
/计数(c.事件发生次数)>=32
和(最大值)(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
-闵(
TO_CHAR(TO_DATE(c.event_dt,'yyyyy-MM-DD'),'MMDD'))
/计数(c.事件发生次数)<91
然后
“夸特利”
其他的
“每年”
结束
来自ps_ca_bp_事件c
按合同编号分组;

事件列的数据类型是什么?另外,为什么要将日期转换为字符串并减去它们?目的是什么?如果要找出两个日期之间的间隔天数,请考虑如果同一年的最大日期是12月12日,最小日期是11月31日,您可能会得到什么结果。如果它们是e在不同年份?event_dt列是日期类型。如果它已经是日期,为什么要对它执行
TO_Date
?我刚刚删除了TO_Date()函数,查询工作正常…非常感谢您的及时响应…我真的很感谢您!!:)
define REGEX_DATE = "'your regex pattern goes here'"
    DEFINE REGEX_DATE = "'your regex pattern goes here'"

    SELECT   c.contract_num,
         CASE
            WHEN REGEXP_INSTR(c.event_dt, &REGEX_DATE) = 0 THEN NULL
            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;