XML 文書のメリットの一つは、リレーショナル・データに比べて柔軟性が高いことで す。仕様変更により XML ツリーを構成している要素の追加、変更、削除が発生すること があります。XML スキーマを指定しない非構造化記憶域については、XML 文書の構造に 特に制約はありませんが、構造化記憶域では、XML 文書の要素内容や属性とリレーショ ナ ル 列 が 紐 づ い て お り 、XML ス キ ー マ の 変 更 は 難 し い と さ れ て き ま し た 。Oracle
Database 10gリリース1よりCopyEvolveプロシージャが用意され、XMLスキーマの変
更に合わせて内部のオブジェクト構成を自動的に変更し、登録済みの XML 文書の内容を 変更することができます。ただし、プロシージャの実行中は表や列への参照ができません。
ここでは、構造化記憶域モデルにおけるXMLスキーマの変更方法を紹介します。
<?xml version="1.0" encoding="EUC-JP"?>
<顧客 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.oracle.com/apps"
xsi:schemaLocation="http://www.oracle.com/apps http://www.oracle.com/apps">
<顧客番号>1</顧客番号>
<氏名>オラクル太郎</氏名>
<郵便番号>221-2212</郵便番号>
<住所>東京都千代田区紀尾井町1-2-3</住所>
<生年月日>1991-12-03</生年月日>
<性別区分>M</性別区分>
</顧客>
リスト6-1 XML文書例(仕様変更前)
変更要求:
’/顧客/氏名’要素の次に’メールアドレス’要素を追加。
変更前の XML 文書の’メールアドレス’要素の内容に、’[email protected]’という 文字列を埋め込む。
以下の手順で対応します。
1. 新しい定義のXMLスキーマを作成
2. 既存のXMLデータが新しいXMLスキーマに対応するためのXSLTを作成 3. DBMS_XMLSCHEMA.CopyEvolveプロシージャを実行
変更前の環境から作成し、動作を確認します。
始めに、変更前のXMLスキーマを登録します。
SQL> DECLARE
2 doc clob := '<?xml version="1.0" encoding="EUC-JP"?>
3 <xsd:schema xmlns="http://www.oracle.com/apps"
4 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
5 xmlns:xdb="http://xmlns.oracle.com/xdb"
6 targetNamespace="http://www.oracle.com/apps"
7 elementFormDefault="qualified">
8 <xsd:element name="顧客" xdb:defaultTable="CUST">
9 <xsd:complexType>
10 <xsd:sequence>
11 <xsd:element name="顧客番号" type="xsd:integer"/>
12 <xsd:element name="氏名" type="xsd:string"/>
13 <xsd:element name="郵便番号" type="xsd:string"/>
14 <xsd:element name="住所" type="xsd:string"/>
15 <xsd:element name="生年月日" type="xsd:date"
16 nillable="true"/>
17 <xsd:element name="性別区分">
18 <xsd:simpleType>
19 <xsd:restriction base="xsd:string">
20 <xsd:enumeration value=""/>
21 <xsd:enumeration value="M"/>
22 <xsd:enumeration value="F"/>
23 </xsd:restriction>
24 </xsd:simpleType>
25 </xsd:element>
26 </xsd:sequence>
27 </xsd:complexType>
28 </xsd:element>
29 </xsd:schema>';
30 BEGIN
31 dbms_xmlschema.registerSchema(
32 schemaURL => 'http://www.oracle.com/apps', 33 schemaDoc => doc,
34 genTables => true, 35 local => true);
36 END;
37 /
リスト6-2 既存のXMLスキーマを登録
ス キ ー マ 注 釈 の xdb:defaultTable="CUST" の 定 義 と DBMS_XMLSCHEMA.RegisterSchema プロシージャの’genTables’パラメ ータを’true’に設定することにより、XML スキーマを登録したタイミン グで”CUST”のXMLType 表が作られるのでCREATE TABLE 文が不要に なります。
次に、XML文書を登録します。
SQL> INSERT INTO CUST
2 VALUES(XMLType('<?xml version="1.0" encoding="EUC-JP"?>
3 <顧客 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns="http://www.oracle.com/apps"
5 xsi:schemaLocation="http://www.oracle.com/apps 6 http://www.oracle.com/apps">
7 <顧客番号>1</顧客番号>
8 <氏名>オラクル太郎</氏名>
9 <郵便番号>221-2212</郵便番号>
10 <住所>東京都千代田区紀尾井町1-2-3</住所>
11 <生年月日>1991-12-03</生年月日>
12 <性別区分>M</性別区分>
13 </顧客>'));
リスト6-3 XML文書の登録
SQL> SELECT * FROM cust;
SYS_NC_ROWINFO$
---
<?xml version="1.0" encoding="EUC-JP"?>
<顧客 xmlns="http://www.oracle.com/apps"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oracle.com/apps http://www.oracle.com/apps">
<顧客番号>1</顧客番号>
<氏名>オラクル太郎</氏名>
<郵便番号>221-2212</郵便番号>
<住所>東京都千代田区紀尾井町1-2-3</住所>
<生年月日>1991-12-03</生年月日>
<性別区分>M</性別区分>
</顧客>
リスト6-4 XML文書の確認
続けて手順に従いXMLスキーマを更新します。
newSchema 変数に新しい定義のXMLスキーマを、transform変数に XSLTを代 入し、DBMS_XMLSCHEMA.CopyEvolveプロシージャに渡して実行します。
SQL> DECLARE
2 newSchema xmltype;
3 transform xmltype;
4 BEGIN
5 newSchema := xmltype('<?xml version="1.0" encoding="EUC-JP"?>
6 <xsd:schema xmlns="http://www.oracle.com/apps"
7 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
8 xmlns:xdb="http://xmlns.oracle.com/xdb"
9 targetNamespace="http://www.oracle.com/apps"
10 elementFormDefault="qualified">
11 <xsd:element name="顧客" xdb:defaultTable="CUST">
12 <xsd:complexType>
13 <xsd:sequence>
14 <xsd:element name="顧客番号" type="xsd:integer"/>
15 <xsd:element name="氏名" type="xsd:string"/>
16 <xsd:element name="メールアドレス" type="xsd:string"/>
17 <xsd:element name="郵便番号" type="xsd:string"/>
18 <xsd:element name="住所" type="xsd:string"/>
19 <xsd:element name="生年月日" type="xsd:date"
20 nillable="true"/>
21 <xsd:element name="性別区分">
22 <xsd:simpleType>
23 <xsd:restriction base="xsd:string">
24 <xsd:enumeration value=""/>
25 <xsd:enumeration value="M"/>
26 <xsd:enumeration value="F"/>
27 </xsd:restriction>
28 </xsd:simpleType>
29 </xsd:element>
30 </xsd:sequence>
31 </xsd:complexType>
32 </xsd:element>
33 </xsd:schema>');
34 transform := xmltype('<?xml version="1.0" encoding="EUC-JP"?>
35 <xsl:stylesheet version="1.0"
36 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
37 xmlns="http://www.oracle.com/apps"
38 xmlns:p="http://www.oracle.com/apps">
39 <xsl:template match="@*|node()">
40 <xsl:copy>
41 <xsl:apply-templates select="@*|node()"/>
42 </xsl:copy>
43 </xsl:template>
44 <xsl:template match="/p:顧客/p:氏名">
45 <xsl:copy>
46 <xsl:apply-templates select="@*|node()"/>
47 </xsl:copy>
48 <メールアドレス>[email protected]</メールアドレス>
49 </xsl:template>
50 </xsl:stylesheet>');
51 dbms_xmlschema.CopyEvolve(SCHEMAURLS =>
52 xdb$string_list_t('http://www.oracle.com/apps'), 53 NEWSCHEMAS => XMLSequenceType(newSchema), 54 TRANSFORMS => XMLSequenceType(transform), 55 mapTabName => 'BACKTABLE',
56 preserveOldDocs => TRUE);
57 end;
58 /
リスト6-5 XMLスキーマ変更スクリプト
DBMS_XMLSCHEMA.CopyEvolve プロシージャの実行により、Oracle Database 内部で以下の処理が実行されます。
1. 既存のXMLType表または列に格納されているXML文書を一時表にバック アップ
2. 古いバージョンのXMLスキーマ、関連付けされているXML文書を削除 3. 新しいバージョンのXMLスキーマと表を作成
4. 一時表からXSLT変換処理を実行し、新しい表にXML文書を格納
デ フ ォ ル ト で は 、 プ ロ シ ー ジ ャ 実 行 完 了 後 に 一 時 表 が 削 除 さ れ ま す が 、
mapTabName と preserveOldDocs パラメータを設定することにより、変更前の
XML文書を保存できます。
一時表にバックアップされた変更前データを確認します。
SQL> SELECT temp_tabname FROM backtable;
TEMP_TABNAME
--- CUST2862
SQL> SELECT * FROM CUST2862;
DATA
--- OID ACLOID
--- --- OWNERID
---
<?xml version="1.0" encoding="UTF-8"?>
<顧客 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.or
acle.com/apps" xsi:schemaLocation="http://www.oracle .com/apps http://www.oracle.com/apps">
<顧客番号>1</顧客番号>
<氏名>オラクル太郎</氏名>
<郵便番号>221-2212</郵便番号>
<住所>東京都千代田区紀尾井町1-2-3</住所>
<生年月日>1991-12-03</生年月日>
<性別区分>M</性別区分>
</顧客>
17B913C29ADAE65DE0403892BE0C111B
リスト6-6 一時表(変更前データ)の確認
DBMS_XMLSCHEMA.CopyEvolve プ ロ シ ー ジ ャ に よ っ て 変 更 さ れ た 既 存 の XML文書を確認します。
SQL> SELECT * FROM cust;
SYS_NC_ROWINFO$
---
<顧客 xmlns="http://www.oracle.com/apps"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oracle.com/apps http://www.oracle.com/apps">
<顧客番号>1</顧客番号>
<氏名>オラクル太郎</氏名>
<メールアドレス>[email protected]</メールアドレス>
<郵便番号>221-2212</郵便番号>
<住所>東京都千代田区紀尾井町1-2-3</住所>
<生年月日>1991-12-03</生年月日>
<性別区分>M</性別区分>
</顧客>
リスト6-7 変更後のXML文書確認
DBMS_XMLSCHEMA.CopyEvolve プロシージャを実行することにより、既存の XML文書の有効性を保持しながら、登録されたXMLスキーマを拡張しました。