简体   繁体   English

仅在案例声明中增加年份获取无效数字错误-ORA-01722

[英]adding years getting invalid number error in case statement only - ORA-01722

Forgive me as I am new to this. 原谅我,因为我是新手。 I am trying to add a year to a date in a query. 我试图在查询中的日期中添加一年。 The year to be added is based on the month/day in the database. 要添加的年份基于数据库中的月/日。 If the date is prior to November 1st then the year will be 2017 if it is after November 1st then it will be 2018. I have tried this a few ways (see below) and can get the years added in a query but when I put them in a case statement I get the 'Invalid Number' error. 如果日期在11月1日之前,那么年份将是2017年;如果日期在11月1日之后,那么它将是2018年。我尝试了几种方法(请参阅下文),可以在查询中添加年份,但是当我输入他们在案例陈述中,我收到了“无效号码”错误。

Using to_char on the date: 在日期上使用to_char:

   CASE
      WHEN to_char(au.creat_ts, 'MMDD') >= to_char('11/01/2018', 'MMDD') THEN
       to_char(to_date( '2017'||to_char(au.creat_ts,'MMDDHH24MISS'),
'YYYYMMDDHH24MISS' ), 'MM/DD/YYYY') 
      ELSE
      to_char(to_date( '2018'||to_char(au.creat_ts,'MMDDHH24MISS'), 'YYYYMMDDHH24MISS' ), 'MM/DD/YYYY') 
    END cmpltn_dt,

Adding Months: 新增月份:

  CASE
      WHEN to_char(au.creat_ts, 'MMDD') >= to_char('11/01/2018', 'MMDD') THEN
       trunc(add_months(au.creat_ts,
                        floor(months_between(SYSDATE, au.creat_ts) / 12) * 12)) --calcx --add years
      ELSE
       trunc(add_months(au.creat_ts,
                        (floor(months_between(SYSDATE, au.creat_ts) / 12) - 1) * 12))
    END calcx,

These run in select from dual statements with no error. 它们在双语句中的select中运行,没有错误。 Any ideas? 有任何想法吗? Thanks so much in advance. 非常感谢。

If AU.CREAT_TS is DATE , this works OK (meaning: it doesn't fail): 如果AU.CREAT_TSDATE ,则工作正常(意味着:它不会失败):

SQL> with au (creat_ts) as
  2    (select date '2018-12-05' from dual
  3    )
  4  select
  5    CASE WHEN to_char(au.creat_ts, 'MMDD') >= to_char(to_date('11/01/2018', 'dd/mm/yyyy'), 'MMDD') THEN
  6              trunc(add_months(au.creat_ts, floor(months_between(SYSDATE, au.creat_ts) / 12) * 12))
  7         ELSE trunc(add_months(au.creat_ts, (floor(months_between(SYSDATE, au.creat_ts) / 12) - 1) * 12))
  8    END calcx
  9  from au
 10  ;

CALCX
-------------------
05.12.2018 00:00:00

SQL>

Note the difference: you used 注意区别:您曾经

  CASE WHEN to_char(au.creat_ts, 'MMDD') >= to_char('11/01/2018', 'MMDD') THEN 

and it raises the error because '11/01/2018' is a string; 并且因为'11/01/2018'是一个字符串而引发错误; it is not a date. 不是一个约会。 If you want to use a date, you have to tell Oracle so. 如果要使用日期,则必须告诉Oracle。 How? 怎么样? See my working example. 参见我的工作示例。

The errors are coming from the two appearances of this clause: 错误来自此子句的两种出现:

to_char('11/01/2018', 'MMDD')

You're passing a string as the first argument ( not a date), and Oracle defaults to trying to convert that string to a number - which throws the error you see. 您将字符串作为第一个参数( 而不是日期)传递,Oracle默认将尝试将该字符串转换为数字-这会引发您看到的错误。

You either need to pass in an actual date, by explicitly converting the string: 您需要通过显式转换字符串来传递实际日期:

to_char(to_date('11/01/2018', 'MM/DD/YYYY', 'MMDD')

or with an ANSI literal: 或使用ANSI文字:

to_char(date '2018-11-01', 'MMDD')

or if it's really a fixed value don't convert it at all, just do: 或者,如果它确实是固定值,则根本不进行转换,只需执行以下操作:

'1101'

or if you are being passed that streing from elsewhere - and you're sure about the format, of course - us substr() to extract the bits you need without trying to bounce it through a date. 或者,如果您从其他地方传递了这种痕迹-当然,您肯定会知道格式-我们使用substr()提取所需的位,而无需尝试通过日期反弹。

Incidentally, converting values to and from dates and concatenating bits of strings together looks a bit messy and error-prone. 顺便说一句,将值与日期之间的转换以及将字符串的各个位串联在一起看起来有点混乱且容易出错。 And if that fixed date is always the first of a month, you could modify your case expression to only look at the month, eg via extract() . 并且如果该固定日期始终是一个月的第一天,则可以修改case表达式以仅查看该月,例如通过extract()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM