Oracle Database全文搜索报错DRG-10837:section lastname不存在
解决ORA-20000: DRG-10837: section lastname does not exist错误
错误核心原因
你在CONTAINS查询中使用within LASTNAME和within PRIMARYID语法,但你的Oracle Text索引并未为fullname字段定义名为LASTNAME和PRIMARYID的字段区段(Field Section)。同时,普通B树索引无法支持Oracle Text的CONTAINS及within语法,必须使用Oracle Text专用索引并正确配置区段。
分场景解决方案
场景1:LASTNAME和PRIMARYID是Employee表的独立字段
如果这两个是表中单独的字段,不需要在fullname的CONTAINS查询里用within,直接分别对每个字段调用CONTAINS并计算得分即可:
SELECT e.*, (CONTAINS(fullname, 'SAHU*', 1) * 1) + (CONTAINS(primaryid, 'SAHU*', 1) * 2) + (CONTAINS(lastname, 'SAHU*', 1) * 1) AS match_score FROM Employee e WHERE CONTAINS(fullname, 'SAHU*') > 0 OR CONTAINS(primaryid, 'SAHU*') > 0 OR CONTAINS(lastname, 'SAHU*') > 0;
注意:每个需要用CONTAINS的字段,都要单独创建Oracle Text索引(以CONTEXT索引为例):
-- 为fullname创建Oracle Text索引 CREATE INDEX emp_fullname_ctx ON Employee(fullname) INDEXTYPE IS CTXSYS.CONTEXT; -- 为primaryid创建Oracle Text索引 CREATE INDEX emp_primaryid_ctx ON Employee(primaryid) INDEXTYPE IS CTXSYS.CONTEXT; -- 为lastname创建Oracle Text索引 CREATE INDEX emp_lastname_ctx ON Employee(lastname) INDEXTYPE IS CTXSYS.CONTEXT;
场景2:fullname是包含结构化内容的字段
如果fullname字段存储的是包含PRIMARYID和LASTNAME标记的结构化文本(比如XML、自定义格式字符串),需要先给索引配置对应的字段区段:
子场景2.1:XML格式内容
如果fullname是XML格式(如<PRIMARYID>123</PRIMARYID><LASTNAME>SAHU</LASTNAME>),创建索引时指定XML区段组:
CREATE INDEX emp_fullname_ctx ON Employee(fullname) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('SECTION GROUP CTXSYS.XML_SECTION_GROUP');
子场景2.2:自定义分隔符格式
如果是自定义格式(如PRIMARYID: 123; LASTNAME: SAHU),先创建自定义区段组并添加字段区段:
-- 创建自定义区段组 BEGIN CTX_DDL.CREATE_SECTION_GROUP('EMP_SECTION_GROUP', 'BASIC_SECTION_GROUP'); -- 添加PRIMARYID字段区段,指定前缀标记 CTX_DDL.ADD_FIELD_SECTION('EMP_SECTION_GROUP', 'PRIMARYID', 'PRIMARYID:'); -- 添加LASTNAME字段区段,指定前缀标记 CTX_DDL.ADD_FIELD_SECTION('EMP_SECTION_GROUP', 'LASTNAME', 'LASTNAME:'); END; / -- 使用自定义区段组创建索引 CREATE INDEX emp_fullname_ctx ON Employee(fullname) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('SECTION GROUP EMP_SECTION_GROUP');
配置完成后,重新执行你的原始查询即可。
额外注意事项
- 必须使用Oracle Text专用索引(CONTEXT、CTXCAT等),普通B树索引不支持
CONTAINS函数。 - 如果已有旧索引,需先删除(
DROP INDEX emp_fullname_ctx;)再重新创建带区段配置的索引。
内容的提问来源于stack exchange,提问作者Swapnesh Sahu
相关产品推荐
相关产品推荐

