oracle ORA-01839:与sysdate比较时,日期对于指定的月份无效错误

9wbgstp7  于 2023-08-03  发布在  Oracle
关注(0)|答案(1)|浏览(192)

我犯了错误,你知道为什么吗?我在birthyear字段中添加65年,它会出错

SELECT NVL(PERSON.BIRTH_DAY,'01') BIRTH_DAY,
   NVL(PERSON.BIRTH_MONTH,'01') BIRTH_MONTH, 
   NVL(PERSON.BIRTH_YEAR,'2900') BIRTH_YEAR,
   PROFIL.KAYITNO  KAYITNO     
FROM  PERSON PERSON           
  INNER JOIN PROFIL PROFIL ON PERSON.KAYITNO = PROFIL.KAYITNO and 
  STATUS=12  
WHERE  
  (TO_DATE(NVL(BIRTH_DAY,'01')||'.'||NVL(BIRTH_MONTH,'01')||'.'|| 
  (NVL(PERSON.BIRTH_YEAR,'2190')+65), 'dd.mm.yyyy') < SYSDATE);

字符串

egmofgnx

egmofgnx1#

切勿在已经是DATE的值上使用TO_DATE(例如SYSDATE)。TO_DATE接受一个字符串作为第一个参数,因此您要求Oracle隐式地将DATE值转换为字符串,然后显式地将其转换回DATE。在最好的情况下,它是无意义的,什么也不做,在最坏的情况下,它要么引发一个错误(如您所看到的),要么给出一个意外的输出。

如果要将DATE的时间组件设置为午夜,请使用TRUNC而不是TO_DATE

SELECT NVL(KISI.DOGUMGUN,'01') DOGUMGUN,
       NVL(KISI.DOGUMAY,'01') DOGUMAY,
       NVL(KISI.DOGUMYIL,'2900') DOGUMYIL,
       PROFIL.KAYITNO  KAYITNO     
FROM   ORTKISI KISI           
       INNER JOIN ISTPROFIL PROFIL 
       ON KISI.KAYITNO = PROFIL.KAYITNO
          and PRMISARAMASTATUKAYITNO=12  
WHERE  TO_DATE(
         NVL(DOGUMGUN,'01')||'.'
         ||NVL(DOGUMAY,'01')||'.'
         ||(NVL(KISI.DOGUMYIL,'2190')+65),
         'dd.mm.yyyy'
       ) < TRUNC(SYSDATE);

字符串
此外,任何在闰年2月29日出生的人(即偶数年),那么当你把65年加到那个日期上时,2月29日将永远不会是一个有效的日期,因为65年将是奇数年和非闰年,所以在65年的2月只有28天。
因此,即使你的日期都是有效的,你也需要使用ADD_MONTHS来添加65*12个月,而不是直接添加年份。

SELECT NVL(KISI.DOGUMGUN,'01') DOGUMGUN,
       NVL(KISI.DOGUMAY,'01') DOGUMAY,
       NVL(KISI.DOGUMYIL,'2900') DOGUMYIL,
       PROFIL.KAYITNO  KAYITNO     
FROM   ORTKISI KISI           
       INNER JOIN ISTPROFIL PROFIL 
       ON KISI.KAYITNO = PROFIL.KAYITNO
          and PRMISARAMASTATUKAYITNO=12  
WHERE  ADD_MONTHS(
         TO_DATE(
           NVL(DOGUMGUN,'01')||'.'
           ||NVL(DOGUMAY,'01')||'.'
           ||NVL(KISI.DOGUMYIL,'2190'),
           'dd.mm.yyyy'
         ),
         65 * 12
       ) < TRUNC(SYSDATE);


如果这不能解决问题,那么问题可能不是你的查询(尽管你仍然不应该在DATE上使用TO_DATE),而是你的数据,你需要检查你是否有:非闰年的2月29日,或9月31日,或任何月份的32日,等等。我们无法检查,因为您没有提供任何样本数据。
如果您使用的是Oracle 12或更高版本,则可以使用TO_DATE(... DEFAULT ... ON CONVERSION ERROR, ...)捕获转换错误:

SELECT COALESCE(KISI.DOGUMGUN,'01') AS DOGUMGUN,
       COALESCE(KISI.DOGUMAY,'01') AS DOGUMAY,
       COALESCE(KISI.DOGUMYIL,'2900') AS DOGUMYIL,
       PROFIL.KAYITNO AS KAYITNO     
FROM   ORTKISI KISI           
       INNER JOIN ISTPROFIL PROFIL 
       ON KISI.KAYITNO = PROFIL.KAYITNO
          and PRMISARAMASTATUKAYITNO = 12  
WHERE  ADD_MONTHS(
         TO_DATE(
           DOGUMGUN||'.'||DOGUMAY||'.'||KISI.DOGUMYIL
           DEFAULT '01-01-2900' ON CONVERSION ERROR,
           'dd.mm.yyyy'
         ),
         65 * 12
       ) < TRUNC(SYSDATE);


其中,对于样本数据:

CREATE TABLE ORTKISI (dogumgun, dogumay, dogumyil, kayitno) AS
SELECT '29', '02', '1940', 1 FROM DUAL UNION ALL
SELECT '32', '13', '1900', 2 FROM DUAL;

CREATE TABLE ISTPROFIL (kayitno, PRMISARAMASTATUKAYITNO) AS
SELECT 1, 12 FROM DUAL UNION ALL
SELECT 2, 12 FROM DUAL;


输出:
| DOGUMAY| DOGUMYIL| KAYITNO| KAYITNO |
| --|--|--| ------------ |
| 02年2月|一九四零年|一个| 1 |
fiddle

相关问题