概要
Oracle Database(注1) の XMLDB に関する Tips をご紹介します。バリデーションチェックなどの用途で、XML文書に含まれるタグ数をカウントすることがある場合、以下のクエリで確認することができます。
XMLDB
SELECT XMLCast(XMLQuery ('count(//*)' PASSING <列名>
RETURNING CONTENT) AS NUMBER) cnt FROM <表名>;
解説
XMLデータとして、次の3件のデータが INSERT 済みの場合、以下の実行結果となります。XML文書単位でのタグの総数が出力されます。
テストデータ例
'<tag0>100</tag0>' ,'<tag0><tag1>100</tag1></tag0>' ,'<tag0><tag1>100</tag1><tag2>円</tag2></tag0>'
実行結果例
SELECT id , XMLCast(XMLQuery ('count(//*)' PASSING xml
RETURNING CONTENT) AS NUMBER) cnt FROM xmltab;
ID CNT
---------- ----------
1 1
2 2
3 3
ご参考
上記のSELECTを実行する前提となるテーブル作成などのスクリプトは次の通りです。
XMLDB
--テーブル作成
CREATE USER userctx IDENTIFIED BY userctx DEFAULT TABLESPACE "USERS" TEMPORARY TABLESPACE TEMP;
GRANT CONNECT , RESOURCE TO userctx;
CONNECT userctx/userctx
CREATE TABLE xmltab (id NUMBER PRIMARY KEY, xml XMLTYPE);
INSERT INTO xmltab VALUES (1, XMLTYPE('<tag0>100</tag0>'));
INSERT INTO xmltab VALUES (2, XMLTYPE('<tag0><tag1>100</tag1></tag0>'));
INSERT INTO xmltab VALUES (3, XMLTYPE('<tag0><tag1>100</tag1><tag2>円</tag2></tag0>'));
COMMIT;
--XML インデックス作成
CREATE INDEX xmlidx ON xmltab (xml) INDEXTYPE IS XDB.XMLINDEX PARAMETERS('PATH TABLE pathtab (TABLESPACE users) PATH ID INDEX pathid (TABLESPACE users)VALUE INDEX value_idx (TABLESPACE users) ORDER KEY INDEX order_key(TABLESPACE users)') NOPARALLEL;
--コンテキストインデックス作成
EXECUTE CTX_DDL.CREATE_SECTION_GROUP('psg','PATH_SECTION_GROUP');
EXECUTE CTX_DDL.CREATE_PREFERENCE('jv_lexer','JAPANESE_VGRAM_LEXER');
CREATE INDEX xmlidx2 ON xmltab (xml) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('LEXER jv_lexer SECTION GROUP psg TRANSACTIONAL') NOPARALLEL;
--XML インデックスのパス表にコンテキストインデックス作成
CREATE INDEX xmlidx3 ON pathtab (VALUE) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('LEXER jv_lexer SECTION GROUP psg TRANSACTIONAL') NOPARALLEL;
--オプティマイザ統計情報の収集
EXECUTE DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'USERCTX',TABNAME => 'XMLTAB',no_invalidate => FALSE,CASCADE => TRUE);
注釈
使用している Oracle Database のリリースは、11g Release 2 です。