【问题标题】:Create an index on a CLOB column在 CLOB 列上创建索引
【发布时间】:2019-02-27 04:00:34
【问题描述】:

我有一个表interventi,它有这个结构

describe interventi;
Name                           Null     Type
------------------------------ -------- -----------------------
DATAORA                        NOT NULL TIMESTAMP(6)
PARLAMENTARE                   NOT NULL VARCHAR2(16)
TESTO                          NOT NULL CLOB()

其中归档的 dataora 是主键。我用一行填充了这张表

DATAORA                         PARLAMENTARE     TESTO
------------------------------- ---------------- ------------------------------- 
05-JUL-18 12.00.00.000000000 AM MRTMRZ           (CLOB) PIPPO PLUTO PAPERINO

1 rows selected

现在,我想在字段 testo 上创建一个索引

create index idx_testo_interventi
on interventi(testo) indextype is
ctxsys.context;

但是

Error starting at line 1 in command:
create index idx_testo_interventi
on interventi(testo) indextype is
ctxsys.context
Error at Command Line:1 Column:13
Error report:
SQL Error: ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-20000: Oracle Text error:
DRG-10528: primary keys of type TIMESTAMP(6) are not allowed
ORA-06512: at "CTXSYS.DRUE", line 160
ORA-06512: at "CTXSYS.TEXTINDEXMETHODS", line 366
29855. 00000 -  "error occurred in the execution of ODCIINDEXCREATE routine"
*Cause:    Failed to successfully execute the ODCIIndexCreate routine.
*Action:   Check to see if the routine has been coded correctly.

如何创建索引?

【问题讨论】:

    标签: oracle indexing oracle11g


    【解决方案1】:

    稍作调整可能会有所帮助。

    以下是不起作用的:

    SQL> create table interventi
      2    (dataora      timestamp(6) primary key,
      3     parlamentare varchar2(16),
      4     testo        clob);
    
    Table created.
    
    SQL> create index idx_testo_interventi on interventi (testo)
      2    indextype is ctxsys.context;
    create index idx_testo_interventi on interventi (testo)
    *
    ERROR at line 1:
    ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
    ORA-20000: Oracle Text error:
    DRG-10528: primary keys of type TIMESTAMP(6) are not allowed
    ORA-06512: at "CTXSYS.DRUE", line 160
    ORA-06512: at "CTXSYS.TEXTINDEXMETHODS", line 366
    

    你可以这样做:

    • 包括将用作主键的附加列(在我的示例中为 ID)
    • 使用序列填充触发器
    • 到目前为止,您用作主键的列设置为 unique not null(这将就好像它是主键一样 - 没有重复,没有 NULL 值)

    .

    SQL> drop table interventi;
    
    Table dropped.
    
    SQL> create table interventi
      2    (id number    primary key,
      3     dataora      timestamp(6) unique not null,
      4     parlamentare varchar2(16),
      5     testo        clob);
    
    Table created.
    
    SQL> create sequence seqa;
    
    Sequence created.
    
    SQL> create or replace trigger trg_bi_inter
      2    before insert on interventi
      3    for each row
      4  begin
      5    :new.id := seqa.nextval;
      6  end;
      7  /
    
    Trigger created.
    
    SQL> create index idx_testo_interventi on interventi (testo)
      2    indextype is ctxsys.context;
    
    Index created.
    
    SQL>
    

    [编辑:如何运行 CTX_DDL]

    您必须获得运行它的权限。方法如下:以特权用户身份(SYS 是其中之一,如果您没有创建另一个用户)和该软件包上的 GRANT EXECUTE 连接到将要使用它的用户。

    看看这个例子:起初,它不起作用(正如你已经注意到的那样):

    SQL> exec ctx_ddl.sync_index('idx_testo_interventi');
    BEGIN ctx_ddl.sync_index('idx_testo_interventi'); END;
    
          *
    ERROR at line 1:
    ORA-06550: line 1, column 7:
    PLS-00201: identifier 'CTX_DDL' must be declared
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignored
    

    SYS(或其他特权用户,如果你有的话)连接:

    SQL> connect sys@xe as sysdba
    Enter password:
    Connected.
    SQL> grant execute on ctx_ddl to scott;
    
    Grant succeeded.
    

    返回interventi 表(和索引)的所有者:

    SQL> connect scott@xe
    Enter password:
    Connected.
    SQL> exec ctx_ddl.sync_index('idx_testo_interventi');
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    似乎还可以。

    【讨论】:

    • 字段dataora为主键,主键唯一,默认不为空。我不需要另一个 id(dataora 是从另一个表中引用的),也不需要触发器
    • 理论上,据我所知,你真的不需要任何东西。但是,如果您打算在 TESTO 列上创建索引并针对DRG-10528: primary keys of type TIMESTAMP(6) are not allowed 错误消息,您打算如何保留当前数据模型并创建索引?
    • 我采用了旅游解决方案并创建了索引。现在我必须同步它。我使用了以下命令 execute ctx_ddl.sync_index('idx_testo_interventi'); 但 oracle 显示哪个 PLS-00201: identifier 'CTX_DDL' must be declared
    • 我通过添加一个示例来编辑我的消息,该示例显示如何运行ctx_ddl;请看一下。
    • @Littlefoot,ID 栏不需要。您可以将 dataora 从 PK 转换为 UK,这样就可以了。另一方面,如果数据建模者更喜欢在每个表中都有 PK,您可以添加虚拟列,例如“virtual_pk 数字始终生成为 (to_number(to_char(dataora,'yyyymmddhh24missff'))) 主键”。所以不需要触发。 12c 还允许将标识列作为 PK。
    猜你喜欢
    • 2011-07-01
    • 1970-01-01
    • 2011-04-13
    • 2018-10-01
    • 1970-01-01
    • 2013-10-24
    • 2021-12-26
    • 2020-05-04
    • 2015-04-04
    相关资源
    最近更新 更多