Oracle Text入门

来源:这里教程网 时间:2026-03-03 15:49:23 作者:
1.创建Oracle Text用户
在创建Oracle Text索引和使用Oracle Text PL / SQL包之前,需要创建一个具有CTXAPP角色的用户。 该角色可以执行以下操作:
  • 创建和删除Oracle Text索引首选项
  • 使用Oracle Text PL / SQL软件包
    --1.创建用户ctxdev
    CREATE USER ctxdev IDENTIFIED BY oracle default tablespace tbs_ctxdev;
    --2.授予角色给用户ctxdev
    GRANT RESOURCE, CONNECT, CTXAPP TO ctxdev;
    --3.授予CTX PL/SQL程序包的执行权限
    GRANT EXECUTE ON CTXSYS.CTX_CLS TO ctxdev;
    GRANT EXECUTE ON CTXSYS.CTX_DDL TO ctxdev;
    GRANT EXECUTE ON CTXSYS.CTX_DOC TO ctxdev;
    GRANT EXECUTE ON CTXSYS.CTX_OUTPUT TO ctxdev;
    GRANT EXECUTE ON CTXSYS.CTX_QUERY TO ctxdev;
    GRANT EXECUTE ON CTXSYS.CTX_REPORT TO ctxdev;
    GRANT EXECUTE ON CTXSYS.CTX_THES TO ctxdev;
    GRANT EXECUTE ON CTXSYS.CTX_ULEXER TO ctxdev;
    --这些权限已经被授予给CTXAPP角色。 但是由于角色权限在PL/SQL过程中并不总是起作用,因此最安全的方式是将这些权限显式授予已经具有CTXAPP角色的用户。
    SQL> select role,privilege,table_name from role_tab_privs where role='CTXAPP' order by 2,3;
    ROLE		     PRIVILEGE				      TABLE_NAME
    -------------------- ---------------------------------------- --------------------
    CTXAPP		     DELETE				      DR$DICTIONARY
    CTXAPP		     EXECUTE				      CTX_ANL
    CTXAPP		     EXECUTE				      CTX_DDL
    CTXAPP		     EXECUTE				      CTX_ENTITY
    CTXAPP		     EXECUTE				      CTX_OUTPUT
    CTXAPP		     EXECUTE				      CTX_THES
    CTXAPP		     EXECUTE				      CTX_TREE
    CTXAPP		     EXECUTE				      CTX_ULEXER
    CTXAPP		     EXECUTE				      DRIENTL
    CTXAPP		     EXECUTE				      DRITHSL
    CTXAPP		     INSERT				      DR$DICTIONARY
    CTXAPP		     INSERT				      DR$THS
    CTXAPP		     INSERT				      DR$THS_BT
    CTXAPP		     INSERT				      DR$THS_FPHRASE
    CTXAPP		     INSERT				      DR$THS_PHRASE
    CTXAPP		     SELECT				      DR$DICTIONARY
    CTXAPP		     UPDATE				      DR$DICTIONARY
    CTXAPP		     UPDATE				      DR$THS_PHRASE

    如果数据库没有安装Oracle Text,则授予CTXAPP会报如下错误:

    ORA-01919: role 'CTXAPP' does not exist

    此时我们需要给数据库安装Oracle Text,测试环境是12c多租户,可以在PDB(注意要先在CDB中安装,不然下次重启数据库时,检测到CDB中没有Oracle Text,PDB会进入受限模式)中直接安装Oracle Text组件:

    --方法1:执行catctx.sql脚本
    SQL> alter session set container=orcl;
    SQL> select COMP_ID,COMP_NAME,VERSION,STATUS,SCHEMA from user_registry where comp_id='CONTEXT';
    no rows selected
    --1.安装Oracle Text
    SQL> @?/ctx/admin/catctx.sql oracle SYSAUX TEMP NOLOCK  --执行脚本+参数[ctxsys用户密码、用户默认永久sysaux、临时表空间temp、创建后用户是否锁定nolock |lock]
    SQL> col comp_name for a20;
    SQL> set linesize 200;
    SQL> col schema for a20;
    SQL> col status for a20;
    SQL> col version for a20;
    SQL> col comp_id for a20;
    SQL> select COMP_ID,COMP_NAME,VERSION,STATUS,SCHEMA from user_registry where comp_id='CONTEXT';
    COMP_ID 	     COMP_NAME		  VERSION	       STATUS		    SCHEMA
    -------------------- -------------------- -------------------- -------------------- --------------------
    CONTEXT 	     Oracle Text	  12.2.0.1.0	       VALID		    CTXSYS
    --2.安装默认语言首选项
    SQL> @?/ctx/admin/defaults/dr0defin.sql "AMERICAN";
    --方法2:DBCA silent install的方式
    --注意:在12.1.0.2或12.2.0.1中不支持通过DBCA将数据库组件(如Oracle Text)添加到单个PDB。 此功能将在18.1中添加。
    --语法:
    --非多组户环境:
    dbca -silent -configureDatabase -sourceDB <db unique name for RAC or SID for Single Instance db> -sysDBAUserName <user name with SYSDBA privileges> -sysDBAPassword <password for sysDBAUserName user name>] -addDBOption ORACLE_TEXT
    --多租户环境:
    dbca -silent -configurePluggableDatabase -sourceDB <container_name> -pdbName <pluggable_name> -sysDBAUserName SYS -sysDBAPassword <password> -addDBOption ORACLE_TEXT
    --1.安装Oracle Text
    dbca -silent -configureDatabase  -SourceDB lycdb -sysDBAUsername sys -sysDBAPassword oracle -addDBOption ORACLE_TEXT
    --2.安装默认语言首选项
    如果语言不是英语,则安装适当的特定于语言的默认首选项。$ORACLE_HOME/ctx/admin/defaults目录中包含为Oracle Text支持的每种语言创建特定于语言的默认首选项的脚本,例如英语(US),丹麦语(DK),荷兰语(NL),芬兰语(SF),法语 (F),德语(D),意大利语(IT),葡萄牙语(PT),西班牙语(E)和瑞典语(S)。 它们以drdefXX.sql的形式命名,其中XX是国际凭证代码。
    如果不知道国际凭证代码,也可以调用dr0defdp.sql(删除默认首选项)和dr0defin.sql(根据语言名称,安装首选项)
    一般英文用:AMERICAN,中文用SIMPLIFIED CHINESE
    例如,要手动安装德语默认首选项,请以CTXSYS身份登录sqlplus并运行以下语句:
    SQL> connect / sysdba
    SQL> spool defprefs_install.log
    SQL> alter user ctxsys identified by ctxsys account unlock;
    SQL> connect ctxsys/ctxsys
    SQL> @?/ctx/admin/defaults/dr0defdp.sql
    SQL> @?/ctx/admin/defaults/dr0defin.sql "SIMPLIFIED CHINESE";
    SQL> connect SYS/password as SYSDBA
    SQL> alter user ctxsys account lock password expire;
    SQL> spool off

    2.查询应用程序简单体验
    在基本的文本查询应用程序中,用户输入查询词或短语,并期望该应用程序返回与查询最匹配的文档列表。 这样的应用程序涉及创建一个CONTEXT索引并使用CONTAINS对其进行查询。
    通常,查询应用程序需要用户界面。 CONTEXT查询应用程序中提供了一个如何使用CONTEXT索引类型构建这样的查询应用程序的示例。
    下面示例提供了基本的SQL语句,用于加载文本表,为文档建立索引以及查询索引。
    --1.创建存放文本数据的表,并插入数据
    SQL> conn ctxdev/oracle@orcl
    CREATE TABLE docs (id NUMBER PRIMARY KEY, text VARCHAR2(200));
    INSERT INTO docs VALUES(1, '<HTML>California is a state in the US.</HTML>');
    INSERT INTO docs VALUES(2, '<HTML>Paris is a city in France.</HTML>');
    INSERT INTO docs VALUES(3, '<HTML>France is in Europe.</HTML>');
    commit;
    --2.创建Context索引
    --通过在文本列上创建一个CONTEXT索引来为HTML文件建立索引,如下所示。 因为要为HTML编制索引,所以本示例使用NULL_FILTER首选项类型(不进行过滤)和HTML_SECTION_GROUP类型。 如果为PDF,Microsoft Word或其他格式的文档建立索引,请使用CTXSYS.AUTO_FILTER(默认设置)作为FILTER首选项。
    CREATE INDEX idx_docs ON docs(text)
         INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS
         ('FILTER CTXSYS.NULL_FILTER SECTION GROUP CTXSYS.HTML_SECTION_GROUP');
         
    --3.查询表数据
    --查找包含单词France的所有文档:
    COLUMN text FORMAT a40;
    SQL> SELECT SCORE(1), id, text FROM docs WHERE CONTAINS(text, 'France', 1) > 0;
      SCORE(1)	   ID TEXT
    ---------- ---------- --------------------------------------------------------------------------------
    	 4	    2 <HTML>Paris is a city in France.</HTML>
    	 4	    3 <HTML>France is in Europe.</HTML>
    --4.展示文档
    --在实际的应用程序中,可以显示所选文档并突出显示查询词。 Oracle Text使您可以使用CTX_DOC软件包标记文档。可以在SQL * Plus中使用匿名PL/SQL块演示HTML文档标记。 但是,在实际应用程序中,可以在浏览器中显示文档。此PL/SQL示例使用内存中的CTX_DOC.MARKUP版本突出显示文档3中的单词France。它分配了一个临时CLOB(字符大对象数据类型)来存储标记文本,并将其读回到标准输出。 然后在退出之前将CLOB释放:
    SET SERVEROUTPUT ON;
    DECLARE
      mklob CLOB;
      amt   NUMBER := 40;
      line  VARCHAR2(80);
    BEGIN
      CTX_DOC.MARKUP('idx_docs', '3', 'France', mklob);
      DBMS_LOB.READ(mklob, amt, 1, line);
      DBMS_OUTPUT.PUT_LINE(line);
      DBMS_LOB.FREETEMPORARY(mklob);
    END;
    /
    <HTML><<<France>>> is in Europe.</HTML>
    PL/SQL procedure successfully completed.
    --5.数据处理后同步索引
    --创建CONTEXT索引时,需要显式同步索引,以使用对文本表的任何插入,更新或删除来更新索引。可以使用CTX_DDL.SYNC_INDEX过程来执行此操作。
    --插入新数据
    INSERT INTO docs VALUES(4, '<HTML>Los Angeles is a city in California.</HTML>');
    INSERT INTO docs VALUES(5, '<HTML>Mexico City is big.</HTML>');
    commit;
    --提交后没能查询到新数据
    SQL> SELECT SCORE(1), id, text FROM docs WHERE CONTAINS(text, 'city', 1) > 0;
      SCORE(1)	   ID TEXT
    ---------- ---------- --------------------------------------------------------------------------------
    	 4	    2 <HTML>Paris is a city in France.</HTML>
    --将索引与2 Mb的内存同步,然后重新运行查询:     
    SQL> EXEC CTX_DDL.SYNC_INDEX('idx_docs', '2M');
    PL/SQL procedure successfully completed.
    --新数据可以正常查询
    SQL> SELECT SCORE(1), id, text FROM docs WHERE CONTAINS(text, 'city', 1) > 0;
      SCORE(1)	   ID TEXT
    ---------- ---------- --------------------------------------------------------------------------------
    	 4	    2 <HTML>Paris is a city in France.</HTML>
    	 4	    4 <HTML>Los Angeles is a city in California.</HTML>
    	 4	    5 <HTML>Mexico City is big.</HTML>

    3.目录应用程序简单体验
    示例提供了基本的SQL语句,可为出售电子设备(例如相机和CD播放器)的拍卖网站创建目录索引。 每天都会添加新的库存,并且必须将项目描述,投标日期和价格一起存储。
    对于混合查询,该应用程序需要良好的响应时间。 关键是确定用户经常搜索哪些列以创建合适的CTXCAT索引。 对此类索引的查询使用CATSEARCH运算符。
    --1.创建一张库存表并插入数据
    conn ctxdev/oracle@orcl
    CREATE TABLE auction(
    item_id NUMBER,
    title VARCHAR2(100),
    category_id NUMBER,
    price NUMBER,
    bid_close DATE);
    INSERT INTO AUCTION VALUES(1, 'NIKON CAMERA', 1, 400, '24-OCT-2002');
    INSERT INTO AUCTION VALUES(2, 'OLYMPUS CAMERA', 1, 300, '25-OCT-2002');
    INSERT INTO AUCTION VALUES(3, 'PENTAX CAMERA', 1, 200, '26-OCT-2002');
    INSERT INTO AUCTION VALUES(4, 'CANON CAMERA', 1, 250, '27-OCT-2002');
    commit;
    --2.确定可能要检索的条件。 在此示例中,确定所有查询都在title列中搜索商品说明,并且大多数查询都按price排序。 当使用CATSEARCH运算符时,请为文本列指定术语,并为结构化子句指定条件。
    --3.创建子索引以按价格排序
    --创建一个名为auction_set的索引集,并为price列添加一个子索引
    EXEC CTX_DDL.CREATE_INDEX_SET('auction_iset');
    EXEC CTX_DDL.ADD_INDEX('auction_iset','price');
    --4.创建CTXCAT索引
    CREATE INDEX auction_titlex ON AUCTION(title) INDEXTYPE IS CTXSYS.CTXCAT PARAMETERS ('index set auction_iset');
    --5.查询
    COLUMN title FORMAT a40;
    SELECT title, price FROM auction WHERE CATSEARCH(title, 'CAMERA', 'order by price')> 0;
    TITLE					      PRICE
    ---------------------------------------- ----------
    PENTAX CAMERA					200
    CANON CAMERA					250
    OLYMPUS CAMERA					300
    NIKON CAMERA					400
    SQL> SELECT title, price FROM auction WHERE CATSEARCH(title, 'CAMERA', 'price <= 300')>0;
    TITLE					      PRICE
    ---------------------------------------- ----------
    PENTAX CAMERA					200
    CANON CAMERA					250
    OLYMPUS CAMERA					300
    --6.更新表数据,CTXCAT索引会自动更新
    INSERT INTO AUCTION VALUES(5, 'FUJI CAMERA', 1, 350, '28-OCT-2002');
    INSERT INTO AUCTION VALUES(6, 'SONY CAMERA', 1, 310, '28-OCT-2002');
    commit;
    SQL> SELECT title, price FROM auction WHERE CATSEARCH(title, 'CAMERA', 'order by price')> 0;
    TITLE					      PRICE
    ---------------------------------------- ----------
    PENTAX CAMERA					200
    CANON CAMERA					250
    OLYMPUS CAMERA					300
    SONY CAMERA					310
    FUJI CAMERA					350
    NIKON CAMERA					400

    4.分类应用程序简单体验
    分类应用程序的功能是根据文档内容执行某些操作。 这些操作可以包括为文档分配类别ID或将文档发送给用户。 结果是对文档进行分类。
    --1.创建规则表
    conn ctxdev/oracle@orcl
    CREATE TABLE queries (
          query_id      NUMBER,
          query_string  VARCHAR2(80)
        );
    INSERT INTO queries VALUES (1, 'oracle');
    INSERT INTO queries VALUES (2, 'larry or ellison');
    INSERT INTO queries VALUES (3, 'oracle and text');
    INSERT INTO queries VALUES (4, 'market share');
    commit;
    --2.创建CTXRULE索引
    CREATE INDEX queryx ON queries(query_string) INDEXTYPE IS CTXSYS.CTXRULE;
    --3.在SELECT语句的WHERE子句中使用MATCHES运算符可将文档与查询匹配,然后对文档进行分类
    COLUMN query_string FORMAT a35;
    SELECT query_id,query_string FROM queries WHERE MATCHES(query_string, 'Oracle announced that its market share in databases increased over the last year.')>0;
      QUERY_ID QUERY_STRING
    ---------- -----------------------------------
    	 4 market share
    	 1 oracle

  • 相关推荐