ArcGIS Server无法发布FeatureService一例

客户将Oracle数据库中的FeatureClass迁移到新库中,重新将其发布到ArcGIS Server中,发现无法发布Feature Service,但是源库是可以的。

现场环境:

ArcGIS Desktop 10.x
Oracle 11.2.0.1
使用的QueryLayer模式(具体可以参考http://blog.csdn.net/liufeng1980423/article/details/54730177

下面我们重现一下问题现场以及分析解决过:

1.新建一个oracle库,实例为test
2.在test上创建一个用户lf。

SQL> create user lf identified by lf default tablespace lf quota unlimited on lf
;

用户已创建。

SQL> grant connect,resource to lf;

授权成功。

3.使用桌面导入一个测试图层
这里写图片描述
4.注册数据源到ArcGIS Server.

这里写图片描述

  1. 成功发布服务。

这里写图片描述
这里写图片描述

6.新建用户lf1,并将lf中的数据都导入到lf中

SQL> create user lf1 identified by lf1 default tablespace lf quota unlimited on
lf;

用户已创建。

SQL> grant connect,resource to lf1;

授权成功。

SQL> host expdp system/oracle directory=lftmp dumpfile=lf.dmp owner=lf

Export: Release 11.2.0.1.0 - Production on 星期五 2月 24 14:24:05 2017

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Produc
tion
With the Partitioning, OLAP, Data Mining and Real Application Testing options
由于以下参数, 旧有模式处于活动状态:
旧有模式参数: "owner=lf" 位置: Command Line, 替换为: "schemas=lf"
旧有模式设置了 reuse_dumpfiles=true 参数。
启动 "SYSTEM"."SYS_EXPORT_SCHEMA_01":  system/******** directory=lftmp dumpfile=
lf.dmp schemas=lf reuse_dumpfiles=true
正在使用 BLOCKS 方法进行估计...
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE_DATA
使用 BLOCKS 方法的总估计: 12.12 MB
处理对象类型 SCHEMA_EXPORT/USER
处理对象类型 SCHEMA_EXPORT/SYSTEM_GRANT
处理对象类型 SCHEMA_EXPORT/ROLE_GRANT
处理对象类型 SCHEMA_EXPORT/DEFAULT_ROLE
处理对象类型 SCHEMA_EXPORT/TABLESPACE_QUOTA
处理对象类型 SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
处理对象类型 SCHEMA_EXPORT/SEQUENCE/SEQUENCE
处理对象类型 SCHEMA_EXPORT/SEQUENCE/GRANT/OWNER_GRANT/OBJECT_GRANT
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE
处理对象类型 SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
处理对象类型 SCHEMA_EXPORT/TABLE/COMMENT
处理对象类型 SCHEMA_EXPORT/TABLE/TRIGGER
处理对象类型 SCHEMA_EXPORT/TABLE/INDEX/DOMAIN_INDEX/INDEX
. . 导出了 "LF"."KK2"                                  8.782 MB   24728 行
已成功加载/卸载了主表 "SYSTEM"."SYS_EXPORT_SCHEMA_01"
******************************************************************************
SYSTEM.SYS_EXPORT_SCHEMA_01 的转储文件集为:
  C:\LF.DMP
作业 "SYSTEM"."SYS_EXPORT_SCHEMA_01" 已于 14:25:31 成功完成
SQL> host impdp system/oracle directory=lftmp dumpfile=lf.dmp fromuser=lf touser
=lf1

Import: Release 11.2.0.1.0 - Production on 星期五 2月 24 14:26:25 2017

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Produc
tion
With the Partitioning, OLAP, Data Mining and Real Application Testing options
由于以下参数, 旧有模式处于活动状态:
旧有模式参数: "fromuser=lf" 位置: Command Line, 替换为: "remap_schema"
已成功加载/卸载了主表 "SYSTEM"."SYS_IMPORT_FULL_01"
启动 "SYSTEM"."SYS_IMPORT_FULL_01":  system/******** directory=lftmp dumpfile=lf
.dmp remap_schema=lf:lf1
处理对象类型 SCHEMA_EXPORT/USER
处理对象类型 SCHEMA_EXPORT/SYSTEM_GRANT
处理对象类型 SCHEMA_EXPORT/ROLE_GRANT
处理对象类型 SCHEMA_EXPORT/DEFAULT_ROLE
处理对象类型 SCHEMA_EXPORT/TABLESPACE_QUOTA
处理对象类型 SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
处理对象类型 SCHEMA_EXPORT/SEQUENCE/SEQUENCE
处理对象类型 SCHEMA_EXPORT/SEQUENCE/GRANT/OWNER_GRANT/OBJECT_GRANT
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE_DATA
. . 导入了 "LF1 "."KK2"                                8.782 MB   24728 行
处理对象类型 SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
处理对象类型 SCHEMA_EXPORT/TABLE/COMMENT
处理对象类型 SCHEMA_EXPORT/TABLE/TRIGGER
处理对象类型 SCHEMA_EXPORT/TABLE/INDEX/DOMAIN_INDEX/INDEX
作业 "SYSTEM"."SYS_IMPORT_FULL_01" 已于 14:26:39 成功完成
  1. 对lf1中的数据KK2图层发布服务,分析的时候报如下错误:
    这里写图片描述

错误信息,ArcGIS Server认为图层中没有ObjectID字段,因此无法开启Feature Access功能,继续在桌面产品中查看字段信息
这里写图片描述

发现图层中具有OBJECTID字段。那就是另有别原因。
由于在ArcGIS Server发布Feature Access功能的Map Service需要图层具备唯一的OBJECTID字段。但是在
Oracle11g之前(包括)没有原生的自增长字段(这种类型的字段在别的数据库比如SQLSERVER以及PG中早就存在,Oracle在12c才开始具有),但是11g之前可以通过SEQUENCE+TRIGGER实现。

如在此例中的lf用户下,用导入KK2图层后,从数据库层面上看一共建了如下几个对象。

SQL> select object_name,object_type from user_objects where object_type!='LOB' a
nd object_type!='INDEX';

OBJECT_NAME                              OBJECT_TYPE
---------------------------------------- -------------------
SEQ_78666                                SEQUENCE
MDRT_1335A$                              TABLE
MDRS_1335A$                              SEQUENCE
KK2                                      TABLE
BIFER_78666                              TRIGGER

其中MDRT开头的是Oracle Spatial的RTREE索引表,可以不考虑,剩下三个对象分别是KK2是实际存储数据的堆表这个不用解释,另外两个是SEQ_78666为序列,BIFER_78666是TRIGGER.

稍微熟悉数据库的都清楚,序列是生成ID的工具,在很多关系型数据库中都有这个对象,因此不需要进一步分析,在此需要进一步分析的是BIFER_78666这个触发器。

进一步需要分析以下三方面的内容:
A。触发器是建立在哪张表上
B。触发器什么条件下才能被触发,触发几次
C。触发后执行什么操作

A内容可以从以下操作中查询到:

SQL> select table_owner,table_name,base_object_type from user_triggers where trigger_name='BIFER_78666';

TABLE_OWNE TABLE_NAME BASE_OBJECT_TYPE
---------- ---------- ----------------
LF         KK2        TABLE

从结果中看得到触发器是建立在LF.KK2这个表对象上

B内容:

SQL> select trigger_type,triggering_event,fire_once from user_triggers where trigger_name='BIFER_78666';

TRIGGER_TYPE         TRIGGERING_EVENT     FIR
-------------------- -------------------- ---
BEFORE EACH ROW      INSERT               YES

从结果中得到触发器是在插入数据之前触发,每次插入触发一次

C内容:

SQL> set long 10000
SQL> select trigger_body from user_triggers where trigger_name='BIFER_78666';

TRIGGER_BODY
--------------------------------------------------------------------------------

DECLARE BEGIN IF :NEW.OBJECTID IS NULL THEN :NEW.OBJECTID := LF.SEQ_78666.NEXTVA

L; END IF; EXCEPTION WHEN OTHERS THEN RAISE; END;

从触发器的定义上从序列中得到新的ID值,并赋予OBJECTID字段。

至此内部的运行机制就都弄明白了,除了一个地方还不清楚,那就是78666这个数字是如何获取的,这个在后面会介绍。

继续回到问题中,我们查看LF1用户中是否也存在这些对象。

SQL> conn lf1/lf1
已连接。
SQL> select object_name,object_type from user_objects where object_type!='LOB'
nd object_type!='INDEX';

OBJECT_NAME                              OBJECT_TYPE
---------------------------------------- -------------------
SEQ_78666                                SEQUENCE
MDRT_13452$                              TABLE
MDRS_13452$                              SEQUENCE
KK2                                      TABLE
BIFER_78666                              TRIGGER

从查询结果可以看到lf用户中存在的对象在lf1中都存在,那我们打开Oracle的后台SQL跟踪,查看一下后台执行到哪个SQL语句出现的问题,具体操作在此不再介绍可以参考http://blog.csdn.net/liufeng1980423/article/details/6072515

结果最后执行的SQL为

SELECT atc.column_name FROM ALL_TRIGGERS at, ALL_TRIGGER_COLS atc WHERE at.owner = atc.trigger_owner AND at.trigger_name = atc.trigger_name AND at.table_owner = atc.table_owner AND at.table_name = atc.table_name AND at.trigger_type = 'BEFORE EACH ROW' AND at.triggering_event = 'INSERT' AND at.status = 'ENABLD' AND at.table_owner = 'LF1' AND at.table_name = 'KK2' AND at.trigger_name = 'BIFER_78923' 

该查询条件并没有结果

从这个SQL中可以看出来最后的条件是at.trigger_name = ‘BIFER_78923’,并没有查询BIFER_78666 。

这就牵扯到我前面提到的数字的问题,78923以及78666都是从什么地方获取到的。

继续猜测,在数据库上既能保证唯一而且能保证不变的只有对象的OBJECT_ID,继续验证我的猜测是否准确。

SQL> conn lf/lf
已连接。
SQL> select object_id from user_objects where object_name='KK2';

 OBJECT_ID
----------
     78666

SQL> conn lf1/lf1
已连接。
SQL> select object_id from user_objects where object_name='KK2';

 OBJECT_ID
----------
     78923

果然如此。至此原因找到。

当数据从lf用户中导入到lf1中的时候,所有对象都会导入到lf1中,并且名字不会发生变化,但是由于这些对象会重新创建,因此数据库内部所记录的对象ID会发生变化,而ArcGIS是以数据库内部对象的ID作为标识,导致发生冲突。解决方法:

  1. 使用冷备份或者rman这样的物理迁移的方法进行数据库的迁移。

  2. 重新定义序列和触发器,如下:

SQL> rename seq_78666 to seq_78923;

SQL> CREATE OR REPLACE TRIGGER "BIFER_78923" BEFORE INSERT ON LF1.KK2 FOR EACH R
OW DECLARE BEGIN IF :NEW.OBJECTID IS NULL THEN :NEW.OBJECTID := LF1.SEQ_78923.NE
XTVAL; END IF; EXCEPTION WHEN OTHERS THEN RAISE; END;

Trigger created.

SQL> drop trigger bifer_78666;

Trigger dropped.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值