这篇文章继续讨论全文索引的DATASTORE属性,介绍NESTED_DATASTORE。[@more@]全文索引支持将数据存储在多个列中或存储在主子表中,全文索引还支持将数据存储在嵌套表中。嵌套表的例子和主子表比较类似:
首先创建嵌套表对象,并建立嵌套表:
SQL> CREATE TYPE T_NESTED_REC AS OBJECT
2 (
3 LINE_NO NUMBER,
4 TEXT VARCHAR2(100)
5 );
6 /
类型已创建。
SQL> CREATE TYPE T_NESTED_TAB AS TABLE OF T_NESTED_REC;
2 /
类型已创建。
SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, DOCS T_NESTED_TAB, OTHER VARCHAR2(1))
2 NESTED TABLE DOCS STORE AS NESTED_T;
表已创建。
插入数据一般有两种方式,第一种使用直接将数据填入到嵌套表中的方法,当嵌套表包含的记录不多时,采用这种方法给方便。
第二种先初始化行记录,在一次将嵌套表的记录增加到嵌套表中。
SQL> INSERT INTO T VALUES
2 (
3 1,
4 T_NESTED_TAB(T_NESTED_REC(1, 'THIS IS A NESTED TABLE EXAMPLE'),
5 T_NESTED_REC(2, 'THIS IS THE FIRST ROW IN TABLE')),
6 1
7 );
已创建 1 行。
SQL> INSERT INTO T VALUES (2, T_NESTED_TAB(), 1);
已创建 1 行。
SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (1, 'THIS THE SECOND WAY TO INSERT');
已创建 1 行。
SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (2, 'A ROW IN THE NESTED TABLE');
已创建 1 行。
SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (3, 'THIS GRAMMER IS VERY SPECIAL');
已创建 1 行。
SQL> COMMIT;
提交完成。
下面需要在建立一个NESTED_DATASTORE,并设置相应的参数。参数的设置和DETAIL_DATASTORE很类似。
NESTED_COLUMN 设置表中嵌套表列的列名;NESTED_TYPE设置嵌套表使用的对象名称已经对象的用户名;
NESTED_LONENO设置嵌套表中记录的顺序;NESTED_TEXT设置嵌套表中被索引列的名称;BINARY设置是否在嵌套表
记录后增加换行。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_NESTED', 'NESTED_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_COLUMN', 'DOCS');
4 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_TYPE', 'myuser.T_NESTED_TAB');
5 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_LINENO', 'LINE_NO');
6 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_TEXT', 'TEXT');
7 END;
8 /
PL/SQL 过程已成功完成。
在设定NESTED_TYPE时必须指定用户名,否则在建立索引时会出错如下:
DRG-12800: Attribute NESTED_TYPE must have owner name as prefix
最后就可以创建索引了,注意索引创建到OTHER列上,这是由于全文索引不能直接建立在嵌套表的所在列上。
SQL> CREATE INDEX IND_T_OTHER ON T(OTHER) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_NESTED');
索引已创建。
SQL> SELECT ID FROM T WHERE CONTAINS(OTHER, 'SECOND') > 0;
ID
----------
2
SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_NESTED');
CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CONTEXT
*
ERROR 位于第 1 行:
ORA-22904: 嵌套表列的参考无效
最后需要说明的还是索引同步的问题,必须通过修改OTHER列来通知Oracle嵌套表的数据已经发生了变化。同样的,查询也必须对OTHER列进行查询。
首先创建嵌套表对象,并建立嵌套表:
SQL> CREATE TYPE T_NESTED_REC AS OBJECT
2 (
3 LINE_NO NUMBER,
4 TEXT VARCHAR2(100)
5 );
6 /
类型已创建。
SQL> CREATE TYPE T_NESTED_TAB AS TABLE OF T_NESTED_REC;
2 /
类型已创建。
SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, DOCS T_NESTED_TAB, OTHER VARCHAR2(1))
2 NESTED TABLE DOCS STORE AS NESTED_T;
表已创建。
插入数据一般有两种方式,第一种使用直接将数据填入到嵌套表中的方法,当嵌套表包含的记录不多时,采用这种方法给方便。
第二种先初始化行记录,在一次将嵌套表的记录增加到嵌套表中。
SQL> INSERT INTO T VALUES
2 (
3 1,
4 T_NESTED_TAB(T_NESTED_REC(1, 'THIS IS A NESTED TABLE EXAMPLE'),
5 T_NESTED_REC(2, 'THIS IS THE FIRST ROW IN TABLE')),
6 1
7 );
已创建 1 行。
SQL> INSERT INTO T VALUES (2, T_NESTED_TAB(), 1);
已创建 1 行。
SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (1, 'THIS THE SECOND WAY TO INSERT');
已创建 1 行。
SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (2, 'A ROW IN THE NESTED TABLE');
已创建 1 行。
SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (3, 'THIS GRAMMER IS VERY SPECIAL');
已创建 1 行。
SQL> COMMIT;
提交完成。
下面需要在建立一个NESTED_DATASTORE,并设置相应的参数。参数的设置和DETAIL_DATASTORE很类似。
NESTED_COLUMN 设置表中嵌套表列的列名;NESTED_TYPE设置嵌套表使用的对象名称已经对象的用户名;
NESTED_LONENO设置嵌套表中记录的顺序;NESTED_TEXT设置嵌套表中被索引列的名称;BINARY设置是否在嵌套表
记录后增加换行。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_NESTED', 'NESTED_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_COLUMN', 'DOCS');
4 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_TYPE', 'myuser.T_NESTED_TAB');
5 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_LINENO', 'LINE_NO');
6 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_TEXT', 'TEXT');
7 END;
8 /
PL/SQL 过程已成功完成。
在设定NESTED_TYPE时必须指定用户名,否则在建立索引时会出错如下:
DRG-12800: Attribute NESTED_TYPE must have owner name as prefix
最后就可以创建索引了,注意索引创建到OTHER列上,这是由于全文索引不能直接建立在嵌套表的所在列上。
SQL> CREATE INDEX IND_T_OTHER ON T(OTHER) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_NESTED');
索引已创建。
SQL> SELECT ID FROM T WHERE CONTAINS(OTHER, 'SECOND') > 0;
ID
----------
2
SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_NESTED');
CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CONTEXT
*
ERROR 位于第 1 行:
ORA-22904: 嵌套表列的参考无效
最后需要说明的还是索引同步的问题,必须通过修改OTHER列来通知Oracle嵌套表的数据已经发生了变化。同样的,查询也必须对OTHER列进行查询。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/271283/viewspace-1022091/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/271283/viewspace-1022091/