ArcSDE要素类复制粘贴报ORA-00904错误原因分析

1、现象

  同事反映了这样一个问题:数据库是11gr2,ArcSDE是10.1,将SDE中的要素素拖入ArcMap中进行浏览,图形可见但属性表为空,如下图所示:

  

   另外,复制该要素类(以DLTB_TEST为例)向SDE中粘贴时报错:

  Failed to paster YUHANG.DLTB_TEST

  Underlying DBMS error [ORA-00904: "A"."ADD_COL":invalid identifier]

  如下图所示:

  

2、问题分析

  一开始,我怀疑是建表的SQL中对ADD_COL字段加了双引号,即正确的应该写成add_col varchar2(10),而实际上却写成了 "add_col" varchar2(10),导致无法在查询时进行正常的引用。让现场查询了建表的SQL,排除了这一可能性。

  因为不在现场,也无法远程,我让现场开启了10046事件,并使用ArcMap/ArcCatalog重新执行报错的操作,最终得到trace文件。过程如下:

  1)开启 trace

     用sys用户登陆数据库,然后执行:

       alter system set events '10046 trace name context forever,level 12';

  2)使用ArcMap/ArcCatalog执行要素类拷贝-粘贴操作

  3)关闭 trace

       用sys用户登陆数据库,然后执行:

       alter system set events '10046 trace name context off';

  4)查询 trace 目录

        用sys用户登陆数据库,然后执行:

        select value from v$parameter where name like 'diag%'

  5)在上一步查询结果所对应目录中,进入如下子目录 ../diag/rdbms/$db_name/$instance_name/trace/。在该目录下,找到Module name为ArcMap或 ArcCatalog的.trc文件。

 

  在该.trc文件中,发现了如下的SQL在执行时报ORA-00904错误:

  

  经分析,注意到该SQL中竟然用到了A表和D表(增加表与删除表,参见下文链接” ArcGIS Help 10.1 - Oracle 中的地理数据库中的版本化表 “),说明该要素类被registrer as versioned。此时,我大致可以猜到问题原因了:在要素类被注册为版本后,使用SQL给要素表添加了字段,通过ArcMap浏览或粘贴要素类时,关联查询了A表和D表,由于A表缺少后来添加的字段,导致报了ORA-00904错误。

3、错误的复现

  下面我们就来模拟这个过程,以证明以上的猜测。

  1)一开始,要素类DLTB_TEST未注册为版本,此时该要素类没有对应的A表与D表:

  

   此时可以正常浏览和复制粘贴:

  

  2)接着,将要素类DLTB_TEST注册为版本,后台会自动为该要素类创建对应的A表与D表,分别是A36与D36(如下图的动画):

  

   此时仍然可以正常浏览和复制粘贴。

  3)然后,使用SQL为要素表DLTB_TEST增加字段ADD_COL:

  

   此时在ArcMap中重新加载DLTB_TEST要素类(需要关闭连接后重新连接数据库),已经无法浏览属性表,复制粘贴也会报错(见下图的动画):

  

  4)现在可以看到,DLTB_TEST和A36的结构有差异(少了add_col字段):

  

  5)删除DLTB_TEST新增的ADD_COL字段,重新加载DLTB_TEST要素类(需要关闭连接后重新连接数据库),错误消失。

  

4、正确的处理方式

  现在我们知道了错误产生的原因,如果实际场景中已经存在了这样的问题(即注册为版本后,又通过SQL新增了字段),我们至少可以有以下几种处理方式:

  1)通过SQL删除要素表中多余字段,如第3章第5)步所示。

       如果这些字段不是必须的,删除之后问题就解决了。

     但如果这些字段是必须的,我们可以在删除之后使用ArcMap-属性表-Add Field将删除的字段加回来,这样可以保持要素表与A表的一致性。

  2)取消注册为版本。

       如果不需要使用版本特性,取消注册之后问题就解决了。因为取消注册为版本后,A表和D表会被删除,查询要素表时也不再会关联查询A表和D表。

      但如果还需要使用版本特性,则重新注册为版本即可。重新注册为版本会重新创建A表与D表,此时A表的结构就与要素表结构保持一致了。

5、总结

  对于SDE中的要素表,使用SQL修改其结构和记录往往是不恰当的做法,这样容易引起一致性的问题,而是应该使用AE接口或ArcMap工具进行操作。上述案例,其本质就是一个一致性问题,即要素表与其对应的A表结构不一致,究其原因,就是使用SQL仅调整了要素表的结构,而未将A表的结构保持同步。

6、参考资料

posted @ 2021-12-05 16:51  6宇航  阅读(712)  评论(0编辑  收藏  举报