关于“NULL索引表键值”错误的一点说明

1、错误说明

A和B是两张空间表,均含有SDE.ST_GEOMETRY类型的字段(字段名为shape)。当对这两张表进行空间查询:

select * from a,b where sde.st_intersects(a.shape,b.shape)=1;

报了如下的错误:

其实错误提示信息也很明确了:在查询索引表时,当赋予的键值为NULL时,ODCIIndexFetch()会抛出异常。空间索引的键值是根据geometry的范围计算得到的外包矩形,即一个矩形范围,当geometry自身为null时,外包矩形自然也是null,此时就产生了NULL索引表键值的错误。

2、错误分析

错误提示倒是好理解,现在我们需要知道到底是哪些记录的shape字段为空,进而导致了上图所见的异常,于是发出查询:

   Select objectid, shape as sp from a where sde.st_isempty(shape)=1;

   Select objectid, shape as sp from b where sde.st_isempty(shape)=1;

返回结果都是空的。但我们去看数据,却发现B表中有一条记录的shape字段明明是空的呀,如下图OBJECTID=18684的记录:

怎么回事?

……

那换一个写法试试:

咦,换个写法竟然查出来了。那么sde.st_isempty到底是在查什么呢?我们来看一下这个方法的具体实现:

当shape字段的geometry为null时,直接返回null;当numpts属性>0或len属性>0时,图形非空,返回0;其他情况图形为空,返回1。原来这里的isempty和null是不同的语义

 

下面,我们分别制造一个null的图形和空的图形。

1)当shape字段未赋值时,shape字段的geometry为null。此时sde.st_isempty得到的结果即不是0也不是1,而是null。我们来验证一下:

这里有个疑问:当geometry为null时,会报上图的异常吗?答案是:会的,这种情况下会报"NULL索引表键值"错误

 

2)当为shape字段赋予一个numpts=0的空图形(可通过如下方法构造一个空图形)

此时sde.st_isempty得到的结果是1。我们来验证一下:

这里也有个疑问:当geometry为空时,会报上图的异常吗?答案是:也会的,这种情况下也会报"NULL索引表键值"错误

3、总结

1)当ORACLE SQL的执行计划使用空间索引时,若向空间索引传入了null图形或空图形,会产生ORA-06502:"NULL索引表键值"异常。

例如执行SQL:

Select * from a,b where sde.st_intersects(a.shape,b.shape)=1;

若执行计划使用了A表的空间索引,且B表记录中存在null图形或空图形,会产生上述异常。

2)sde.st_isempty=1的图形与null是不同的语义,代表了不同的含义。

posted @ 2020-03-18 20:33  6宇航  阅读(569)  评论(0编辑  收藏  举报