Heute geht es um einen eher unscheinbaren Parameter beim Erstellen eines Oracle TEXT Index:
Mit FORMAT COLUMN kann zum einen der Filter für Binärdokumente gesteuert werden - darüber hinaus
kann man damit aber auch festlegen, ob das Dokument überhaupt indiziert werden soll. Und das geht so - wir fangen mit einer einfachen Tabelle an:
Mit FORMAT COLUMN kann zum einen der Filter für Binärdokumente gesteuert werden - darüber hinaus
kann man damit aber auch festlegen, ob das Dokument überhaupt indiziert werden soll. Und das geht so - wir fangen mit einer einfachen Tabelle an:
create table test( id number(10) not null, text varchar2(4000) not null, format varchar2(10) not null, constraint pk_test primary key (id), constraint ck_format check (format in ('TEXT','BINARY','IGNORE')) ) / insert into test values (1, 'Dieses Dokument wird indiziert.', 'TEXT') / insert into test values (2, 'Hierfür stehen keine Einträge im Textindex', 'IGNORE') /
Die Indexerstellung funktioniert wie immer - nur, dass der Parameter FORMAT_COLUMN mitgegeben wird.
create index ft_test on test (text) indextype is ctxsys.context parameters ('format column format') /
Danach schauen wir in die $I-Tabelle - dort stehen in der Tat nur Tokens für das erste
Dokument - die Spalte FORMAT enthält hier "TEXT".
Dokument - die Spalte FORMAT enthält hier "TEXT".
SQL> select token_text from dr$ft_test$i; TOKEN_TEXT ------------------------------------------ DIESES DOKUMENT INDIZIERT WIRD 4 Zeilen ausgewählt.
Aber was passiert, wenn man die Spalte FORMAT ändert - angenommen, wir ändern den Inhalt
für das zweite Dokument von IGNORE in TEXT ...
für das zweite Dokument von IGNORE in TEXT ...
SQL> update test set format = 'TEXT' where id = 2 / 1 Zeile aktualisiert.
Wenn man nun in der Dictionary View CTX_USER_PENDING nachsieht, ändert sich diese
(obwohl mit der Spalte FORMAT eine "index-relevante" Spalte geändert wurde, nicht. Ein CTX_DDL.SYNC_INDEX
bewirkt also ebenfalls nichts. Man muss
also entweder im Update-Kommando selbst oder mit einem Trigger sicherstellen, dass bei einer
Änderung der Spalte FORMAT auch die Indexspalte selbst "angefasst" wird - das könnte so
aussehen ...
(obwohl mit der Spalte FORMAT eine "index-relevante" Spalte geändert wurde, nicht. Ein CTX_DDL.SYNC_INDEX
bewirkt also ebenfalls nichts. Man muss
also entweder im Update-Kommando selbst oder mit einem Trigger sicherstellen, dass bei einer
Änderung der Spalte FORMAT auch die Indexspalte selbst "angefasst" wird - das könnte so
aussehen ...
create or replace trigger tr_upd_format before update of format on test for each row begin if :old.format != :new.format then :new.text := :old.text; end if; end; /
Von nun an wirkt eine Änderung an der Spalte FORMAT wie eine Änderung am Dokument - nach der
Index-Synchronisierung ist das Dokument indiziert bzw. aus dem Index entfernt (je nachdem, wie
die Spalte FORMAT gesetzt wurde).
Index-Synchronisierung ist das Dokument indiziert bzw. aus dem Index entfernt (je nachdem, wie
die Spalte FORMAT gesetzt wurde).
SQL> update test set format = 'IGNORE' where id = 1; 1 Zeile wurde aktualisiert. SQL> update test set format = 'TEXT' where id = 2; 1 Zeile wurde aktualisiert. SQL> select pnd_rowid from ctx_user_pending; PND_ROWID ------------------------------ AAAmVGAAFAAAMWTAAA AAAmVGAAFAAAMWTAAB 2 Zeilen ausgewählt. SQL> exec ctx_ddl.sync_index('FT_TEST'); PL/SQL-Prozedur erfolgreich abgeschlossen. SQL> exec ctx_ddl.optimize_index('FT_TEST', ctx_ddl.optlevel_full); PL/SQL-Prozedur erfolgreich abgeschlossen. SQL> select token_text from dr$ft_test$i; TOKEN_TEXT ---------------------------------------------------------------- EINTRÄGE HIERFÜR IM KEINE STEHEN TEXTINDEX 6 Zeilen ausgewählt.