无法过滤空的Datetime值

时间:2018-12-19 16:21:20

标签: oracle

我有一个使我发疯的问题。我必须查询返回一些DATETIME值的oracle视图。 令人难以置信的问题是,即使我在WHERE子句上设置了“ IS NOT NULL”,即使我设置了NVL(FECHA_HASTA,FECHA_DESDE),我仍然会得到空值!那怎么可能??

enter image description here

这是查询:

SELECT CUIL as Cuil, 
    COD_TIPO_CAUSAL as CodTipoCausal, 
    COD_CONVENIO as CodConvenio, 
    FECHA_DESDE as FechaDesde, 
    NVL(FECHA_HASTA, FECHA_DESDE) as FechaHasta
FROM ORGANISMO.VCAUSAL_AUSENCIA
WHERE FECHA_HASTA IS NOT NULL
AND FECHA_HASTA > (SELECT SYSDATE - 180 FROM SYS.DUAL)
AND CUIL IN (SELECT CUIL FROM ORGANISMO.VEMPLEADO WHERE FECHA_EGRESO IS NULL OR FECHA_EGRESO > (SELECT SYSDATE FROM SYS.DUAL))

编辑:

在这里添加了dump(fecha_hasta,1016):

enter image description here

1 个答案:

答案 0 :(得分:2)

转储的值表明数据已损坏。 internal date format is well-known

byte 1 - century (excess 100)  
byte 2 - year (excess 100)  
byte 3 - month  
byte 4 - day  
byte 5 - hour (excess 1)  
byte 6 - minute (excess 1)  
byte 7 - seconds (excess 1)  

因此,SQL Developer报告为空的两个值中的第四个字节(即使它们显然实际上并不为空)也不应为零,因为没有天为零。

基于这些规则,十六进制的79,9d,2,0,18,3c,3c(十进制的121,157,2,0,24,60,60)应转换为:

century: 121 - 100 = 21
year: 157 - 100 - 57
month: 2
day: 0
hour: 24 - 1 = 23
minute: 60 - 1 = 59
second: 60 - 1 = 59

或2157-02-00 23:59:59。同样,78,b8,1,0,18,3c,3c转换为2084-01-00 23:59:59。

SQL Developer版本18.3在前一天的脚本输出和查询结果窗口中显示这些值:

DT                  DUMPED                             
------------------- -----------------------------------
01-07-2020 23:59:59 Typ=12 Len=7: 78,78,7,1,18,3c,3c   
31-01-2157 23:59:59 Typ=12 Len=7: 79,9d,2,0,18,3c,3c   
31-12-2083 23:59:59 Typ=12 Len=7: 78,b8,1,0,18,3c,3c   
01-07-2018 00:00:00 Typ=12 Len=7: 78,76,7,1,1,1,1      

db<>fiddle显示零时值。

因此,由于它们实际上不是null,因此is not nullnvl()不会影响它们是合理的,然后由客户机或应用程序决定如何呈现它们。

真正的问题是,您似乎在查询所依据的视图的表中损坏了数据,因此需要进行调查和修复-假设可以安全地标识无效值,然后您可以找出它们的含义。应该排在第一位,这可能是一个斗争。只是将它们过滤掉,无论是在视图中还是在查询中,都不会很简单-除非您将来可以过滤掉日期。并假设所有的腐败现象都是显而易见的,并推向未来。在某种程度上,您必须质疑所有这些日期的有效性...可能会有更多看起来不错的细微损坏。

然后,需要跟踪并修复造成损坏的任何过程或工具,以免再次发生。当然,很多事情都可能导致损坏,但是我相信imp曾经有一个可能损坏日期和数字的错误,OCI程序也可能会损坏。