ArcMap导入GDB数据至SDE报错ORA-00955名称已由现有对象使用解决方法

2026-09-01 开发技术 4 次阅读 0 次点赞
文章记录了排查ArcGIS数据导入Oracle数据库时遭遇ORA-00955错误的完整过程。问题表象是向SDE粘贴数据时提示对象名称已被占用,但未指明具体冲突对象。通过逐层排查,作者发现根因在于SDE的序列SEQ_ST_INDEX_ID失步,其当前值(169)远小于空间索引登记表中已使用的最大ID(945)。该序列负责分配空间索引编号,失步导致新索引编号与已有辅助表S<ID>_IDX$重名。此外还发现S0_IDX$是每次建索引的临时构建表,失败后残留会加剧问题。解决方案是将序列调整至最大ID之上并清理残留表。文章还顺带提及了ORA-28595错误(EXTPROC路径配置问题)及排查SQL清单。

从一条弹窗开始

同事使用 ArcMap 10.0 从 GDB 往 SDE 里粘贴数据,弹了个窗:

ArcMap导入数据到SDE报ORA-00955错误

粘贴 CZRQ 失败
Underlying DBMS error [Error executing PL/SQL Block
db_stgeom_create_index::ORA-29855:执行 ODCIINDEXCREATE 例行程序时出错
ORA-00955: 名称已由现有对象使用]

ORA-00955,名字被占了。谁占的?占的哪个名字?弹窗里一个字都没写。剩下的事情就是一层层把它挖出来。

先交代环境:ArcSDE 10.0(Build 685)+ Oracle 10.2.0.3,单机部署,SDE 是空间库 owner。CZRQ 数据集里有十几个图层,物理表名是 AGAS 前缀(比如 AGASFAMENAGASTIAOYAXIANG)。顺便说一句,这个坑和数据集内容没关系,换个数据集一样踩。

第一层:日志里发生了什么

ArcSDE 的日志(sde_esri_sde.log)能看到这次粘贴的轨迹:12:05 到 12:06 之间,一批图层表陆续建了出来,每个表一个 R9xx_sde_rowid_uk 唯一索引,一路建到 R950。然后,日志突然断在那里,再也没有动静。

几个小时后出现 ORA-03114 未连接到 ORACLE,giomgr 重新初始化。也就是说,导入是在建索引的当口掉线的,掉线前已经建了半批对象。这类半成品是后面一切问题的起点。

第二层:库里留下了一个孤儿 S0_IDX$

查最近三天新建的对象:

SELECT owner, object_name, object_type, created
  FROM dba_objects
 WHERE created > SYSDATE - 3
 ORDER BY created;

结果里绝大多数是回收站的 BIN$ 对象(表被回滚删掉了),但有三个活的

  • S0_IDX$(TABLE)
  • S0$_IX1S0$_IX2(INDEX,挂在 S0_IDX$ 上)

它们挂着 S0 前缀,明摆着是 ST_Geometry 的东西。ST_Geometry 在 Oracle 里有个坑:官方文档写得很清楚,空间索引除了本身的域索引,还会建一张附属的 S 表,命名规则和 SDE.ST_GEOMETRY_INDEX 里的 INDEX_ID 挂钩,比如 INDEX_ID 为 16 的索引,辅助表就叫 S16_IDX$

也就是说,S0_IDX$ 是某个 INDEX_ID=0 的空间索引留下的辅助表。创建它的那次操作没写完,表留下了,登记没留下,成了孤儿。

第三层:三方对照,孤儿只有它一个

把三张清单摆到一起对账:

  1. SDE.ST_GEOMETRY_INDEX 里所有已登记的空间索引(INDEX_ID 从 1 到 945,共 119 条)
  2. dba_tables 里所有 S%_IDX$ 辅助表
  3. dba_indexes 里所有 DOMAIN 类型的域索引(A###_IX1 系列)

对完发现:除了 S0_IDX$,其他 119 个辅助表和域索引全部对得上号。这个对账过程很值,它把所有"疑似"都排除了,只剩一个明确目标。

删掉它:

DROP TABLE SDE.S0_IDX$ PURGE;
PURGE DBA_RECYCLEBIN;

注意:PURGE DBA_RECYCLEBIN 需要DBA权限才能执行。

第四层:删了还报错,说明撞名另有其人

重新粘贴,还是同样的 ORA-955。但这次观察到一个关键细节:S0_IDX$ 在粘贴瞬间又被新建了一次(15:24:08)。也就是说,它根本不是残留物,而是每次建空间索引时 SDE 都要建的构建表。失败后没人收拾它,下一次建索引先撞上它,于是每次都报 ORA-955。

那这次失败撞的是谁?失败只留下了新建的 S0_IDX$,没有别的对象。说明撞名发生在"建完 S0_IDX$ 之后、建正式辅助表 S<INDEX_ID>_IDX$ 时"。要找到这个编号,去看序列。

第五层:真正的根因,一个失步的序列

查 SDE 名下所有序列:

SELECT sequence_name, last_number
  FROM dba_sequences
 WHERE sequence_owner='SDE'
 ORDER BY sequence_name;

重点来了:

SEQ_ST_INDEX_ID    169

ST_GEOMETRY_INDEX 里的 INDEX_ID 已经用到 945

SEQ_ST_INDEX_ID 就是分配 INDEX_ID 的序列,但它停在 169,比表里的实际最大值落后了一大截。这意味着每次新建空间索引,SDE 从序列拿到的编号都落在 169~256 这段区间——而这些编号对应的 S169_IDX$S170_IDX$……全都已经存在了。于是建辅助表 S<INDEX_ID>_IDX$ 时必撞名,一次都跑不掉。

至于序列为什么落后,大概率是之前某次操作重建或重置过它。具体的"谁干的"已经查不到了,但修复本身很简单。

解决方法

把序列拨到超过当前最大 INDEX_ID 的位置:

ALTER SEQUENCE SDE.SEQ_ST_INDEX_ID INCREMENT BY 2000;
SELECT SDE.SEQ_ST_INDEX_ID.NEXTVAL FROM DUAL;
ALTER SEQUENCE SDE.SEQ_ST_INDEX_ID INCREMENT BY 1;

再清掉上次失败留下的构建表:

DROP TABLE SDE.S0_IDX$ PURGE;
PURGE DBA_RECYCLEBIN;

然后重新粘贴。这次成功了。

排查中顺带发现的第二个坑:ORA-28595

为了验证,我用 SQL*Plus 手工建了一张测试表插数据,结果撞上另一个报错:

ORA-28595: Extproc 代理: DLL 路径无效
ORA-06512: 在 "SDE.ST_GEOMETRY_SHAPELIB_PKG", line 12

这是 ST_Geometry 的形状库 DLL(10.0 里是 st_shapelib.dll)通过 EXTPROC 加载失败。查登记路径:

SELECT library_name, file_spec FROM dba_libraries WHERE owner='SDE';

再核对文件在不在,不对就重建库对象:

CREATE OR REPLACE LIBRARY SDE.ST_GEOMETRY_SHAPELIB AS
  'C:\Program Files (x86)\ArcGIS\ArcSDE\ora10gexe\bin\st_shapelib.dll';
GRANT EXECUTE ON SDE.ST_GEOMETRY_SHAPELIB TO PUBLIC;

这个错不影响 ArcGIS 粘贴(粘贴走 SDE 服务进程,不一定经过 EXTPROC),但业务系统如果直接写 SQL 调 ST_Geometry 函数,就会受影响。有直连 SQL 用空间数据的,值得一并排查。

经验总结

  1. ORA-00955 这类报错查不出撞名对象时,别只看报错,去对账。 系统表、辅助表、域索引三方一对比,孤儿立刻现形。
  2. ST_Geometry 空间索引的命名要记住:辅助表 = S<INDEX_ID>_IDX$INDEX_IDSDE.SEQ_ST_INDEX_ID 分配。 这个知识点能帮你判断撞的是谁。
  3. S0_IDX$ 是每次建空间索引的构建表,不是永久对象。 它反复出现不要慌,导入失败后清理掉即可,但要注意它只是"表",序列失步才是它反复作祟的原因。
  4. 序列和表的数据不一致,是这类"名字被占用"问题的重灾区。 序列落后、重复、被重置,都会造成新对象撞旧对象。检查序列的 last_number 和对应表的实际最大值,应该成为这类排查的固定动作。
  5. 导入中途掉线是产生半成品对象的温床。 这次问题能发酵成连锁故障,源头就是 12:06 那一次连接中断。sqlnet.ora 里加一句 SQLNET.EXPIRE_TIME=10,能减少空闲连接被防火墙掐掉的情况。更重要是:导入大数据集时,挑业务空闲时段,别去动它。

排查 SQL 清单

-- 1. 最近新建的对象,找残留
SELECT owner, object_name, object_type, created
  FROM dba_objects WHERE owner='SDE' AND created > SYSDATE - 1/24;

-- 2. 空间索引登记情况
SELECT * FROM SDE.ST_GEOMETRY_INDEX ORDER BY INDEX_ID;

-- 3. 辅助表清单
SELECT owner, table_name FROM dba_tables
 WHERE owner='SDE' AND table_name LIKE 'S%_IDX$';

-- 4. 域索引(空间索引本体)
SELECT index_name, table_name, status FROM dba_indexes
 WHERE owner='SDE' AND index_type='DOMAIN' AND index_name NOT LIKE 'BIN$%';

-- 5. 序列(重点查 SEQ_ST_INDEX_ID)
SELECT sequence_name, last_number FROM dba_sequences
 WHERE sequence_owner='SDE' ORDER BY sequence_name;

-- 6. 清理
DROP TABLE SDE.S0_IDX$ PURGE;
PURGE DBA_RECYCLEBIN;
ALTER SEQUENCE SDE.SEQ_ST_INDEX_ID INCREMENT BY 2000;
SELECT SDE.SEQ_ST_INDEX_ID.NEXTVAL FROM DUAL;
ALTER SEQUENCE SDE.SEQ_ST_INDEX_ID INCREMENT BY 1;
标签: ArcGIS
最后更新于2小时前
本文由人工编写,AI优化,转载请注明原文地址: ArcMap导入GDB数据至SDE报错ORA-00955名称已由现有对象使用解决方法

评论 (0)

登录 后发表评论

暂无评论,快来发表第一条评论吧!