在CLOB列上创建索引

时间:2018-09-23 11:49:45

标签: oracle indexing oracle11g

我有一个具有这种结构的表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.

如何创建索引?

1 个答案:

答案 0 :(得分:2)

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

这是行不通的:

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),将用作主键
  • 使用一个序列,使用触发器填充它
  • 到目前为止,您用作主键的
  • 列设置为唯一不为空(这就像它是主键一样-没有重复,没有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>

似乎还可以。