XML Schemaの拡張を使用すると、XML SchemaをOracle XML DBに登録した後に更新できます。
Oracle XML DBでは、W3C XML Schema勧告をサポートしています。XML Schemaに準拠するXMLインスタンス・ドキュメントは、SQLおよびプロトコル(FTP、HTTP(S)、WebDAVなど)を使用して格納および取得できます。XML Schemaは、XML文書の構造指定に加え、XMLとオブジェクト・リレーショナル記憶域間のマッピングを判断します。
Oracle XML DBとともにXML Schemaを使用している開発者にとって、XML文書の内容や構造の変更にどのように対応するかが大きな課題です。環境によっては、新たな法規制、社内の要求または外部の機会などによって生じる変更の必要性の頻度は高く、広範囲にわたる場合があります。
たとえば、XML Schema定義に新しい要素や属性を追加したり、データ型を変更したり、出現回数の最小要件や最大要件を調整したりする必要が生じる場合があります。
そのような場合、既存のインスタンス・ドキュメント(データ)を有効にしたまま(または、有効にして)、既存のアプリケーションの稼働中に、新規要件に対応するようにXML Schemaを拡張する必要があります。
既存のドキュメントにこだわらない場合は、単にXML Schemaに依存するXMLType表を削除して古いXML Schemaを削除し、同じURLで新しいXMLを登録できます。ただしほとんどの場合、既存のドキュメントを新規XML Schemaに対応するように変換して保持する必要があります。
Oracle XML DBは次の2種類のスキーマ拡張をサポートしています。
コピーに基づくスキーマの拡張では、スキーマに準拠するすべてのインスタンス・ドキュメントはデータベースの一時領域にコピーされます。古いスキーマは削除され、変更されたスキーマが登録されます。インスタンス・ドキュメントは、一時領域から新規領域に挿入されます。
インプレースのスキーマの拡張では、既存のデータのコピー、削除、挿入が不要のため、コピーに基づく拡張よりも高速に実行できます。ただし、コピーに基づく拡張にはない制限があります。
一般的に、インプレースの拡張は、記憶域モデルの変更がなく、変更により既存のドキュメントが無効にならない場合(既存のドキュメントが新規スキーマに準拠している場合、または準拠可能な場合)に許可されます。制限およびガイドラインの詳細は、「インプレースのXML Schemaの拡張」を参照してください。
コピーに基づく拡張にはDBMS_XMLSCHEMA.copyEvolve、インプレースの拡張にはDBMS_XMLSCHEMA.inPlaceEvolveというPL/SQLプロシージャがそれぞれ用意されています。この章では、各プロシージャの使用方法について説明し、それに関連するスキーマの拡張方法のガイドラインを提示します。
PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveを使用して、コピーに基づくXML Schemaの拡張を実行します。これにより、既存のインスタンス・ドキュメントが一時XMLType表にバックアップされて、古いバージョンのXML Schemaが削除されて(関連インスタンス・ドキュメントも削除されます)、新しいバージョンが登録されて、バックアップしたインスタンス・ドキュメントが新規XMLType表にコピーされます。
問題が発生した場合、バックアップ・コピーはリストアされます。「プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック」を参照してください。
プロシージャcopyEvolveを使用すると、既存のXMLインスタンス・ドキュメントの有効性を保持しながら、登録されたXML Schemaを拡張できます。
拡張されたバージョンの発注書XML Schemaを示します。これは、コピーに基づくXML Schemaの拡張の使用方法を示す例で使用されます。
例20-1は、例A-2の発注書XML Schemaの修正バージョンのリストの一部を示します。完全な修正スキーマのリストは、例A-3を参照してください。この例では、太字のテキストが新規部分、または元のスキーマと異なる部分です。
例20-1 修正された発注書XML Schema
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0">
<xs:element
name="PurchaseOrder" type="PurchaseOrderType"
xdb:defaultTable="PURCHASEORDER"
xdb:columnProps=
"CONSTRAINT purchaseorder_pkey PRIMARY KEY (XMLDATA.reference),
CONSTRAINT valid_email_address FOREIGN KEY (XMLDATA.userid)
REFERENCES hr.employees (EMAIL)"
xdb:tableProps=
"VARRAY XMLDATA.ACTIONS.ACTION STORE AS TABLE ACTION_TABLE
((CONSTRAINT action_pkey PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
VARRAY XMLDATA.LINEITEMS.LINEITEM STORE AS TABLE LINEITEM_TABLE
((constraint LINEITEM_PKEY primary key (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
lob (XMLDATA.NOTES) STORE AS (ENABLE STORAGE IN ROW STORAGE(INITIAL 4K NEXT 32K))"/>
<xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
<xs:sequence>
<xs:element name="Actions" type="ActionsType" xdb:SQLName="ACTIONS"/>
<xs:element name="Reject" type="RejectionType" minOccurs="0" xdb:SQLName="REJECTION"/>
<xs:element name="Requestor" type="RequestorType" xdb:SQLName="REQUESTOR"/>
<xs:element name="User" type="UserType" xdb:SQLName="USERID"/>
<xs:element name="CostCenter" type="CostCenterType" xdb:SQLName="COST_CENTER"/>
<xs:element name="BillingAddress" type="AddressType" minOccurs="0"
xdb:SQLName="BILLING_ADDRESS"/>
<xs:element name="ShippingInstructions" type="ShippingInstructionsType"
xdb:SQLName="SHIPPING_INSTRUCTIONS"/>
<xs:element name="SpecialInstructions" type="SpecialInstructionsType"
xdb:SQLName="SPECIAL_INSTRUCTIONS"/>
<xs:element name="LineItems" type="LineItemsType" xdb:SQLName="LINEITEMS"/>
<xs:element name="Notes" type="NotesType" minOccurs="0" xdb:SQLType="CLOB"
xdb:SQLName="NOTES"/>
</xs:sequence>
<xs:attribute name="Reference" type="ReferenceType" use="required" xdb:SQLName="REFERENCE"/>
<xs:attribute name="DateCreated" type="xs:dateTime" use="required"
xdb:SQLType="TIMESTAMP WITH TIME ZONE"/>
</xs:complexType>
<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded" xdb:SQLName="LINEITEM"
xdb:SQLCollType="LINEITEM_V"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
<xs:element name="Quantity" type="quantityType"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER"
xdb:SQLType="NUMBER"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T">
<xs:simpleContent>
<xs:extension base="UPCCodeType">
<xs:attribute name="Description" type="DescriptionType" use="required"
xdb:SQLName="DESCRIPTION"/>
<xs:attribute name="UnitCost" type="moneyType" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="ReferenceType">
<xs:restriction base="xs:string">
<xs:minLength value="18"/>
<xs:maxLength value="30"/>
</xs:restriction>
</xs:simpleType>
. . .
<xs:complexType name="RejectionType" xdb:SQLType="REJECTION_T">
<xs:all>
<xs:element name="User" type="UserType" minOccurs="0" xdb:SQLName="REJECTED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_REJECTED"/>
<xs:element name="Comments" type="CommentsType" minOccurs="0" xdb:SQLName="REASON_REJECTED"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ShippingInstructionsType" xdb:SQLType="SHIPPING_INSTRUCTIONS_T">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0" xdb:SQLName="SHIP_TO_NAME"/>
<xs:choice>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="fullAddress" type="FullAddressType" minOccurs="0"
xdb:SQLName="SHIP_TO_ADDRESS"/>
</xs:choice>
<xs:element name="telephone" type="TelephoneType" minOccurs="0" xdb:SQLName="SHIP_TO_PHONE"/>
</xs:sequence>
</xs:complexType>
. . .
<xs:simpleType name="NameType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FullAddressType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
. . .
<xs:simpleType name="DescriptionType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="AddressType" xdb:SQLType="ADDRESS_T">
<xs:sequence>
<xs:element name="StreetLine1" type="StreetType"/>
<xs:element name="StreetLine2" type="StreetType" minOccurs="0"/>
<xs:element name="City" type="CityType"/>
<xs:choice>
<xs:sequence>
<xs:element name="State" type="StateType"/>
<xs:element name="ZipCode" type="ZipCodeType"/>
</xs:sequence>
<xs:sequence>
<xs:element name="Province" type="ProvinceType"/>
<xs:element name="PostCode" type="PostCodeType"/>
</xs:sequence>
<xs:sequence>
<xs:element name="County" type="CountyType"/>
<xs:element name="Postcode" type="PostCodeType"/>
</xs:sequence>
</xs:choice>
<xs:element name="Country" type="CountryType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="StreetType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="128"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CityType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="StateType">
<xs:restriction base="xs:string">
<xs:minLength value="2"/>
<xs:maxLength value="2"/>
<xs:enumeration value="AK"/>
<xs:enumeration value="AL"/>
<xs:enumeration value="AR"/>
. . . -- A value for each US state abbreviation
<xs:enumeration value="WY"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="ZipCodeType"> <xs:restriction base="xs:string"> <xs:pattern value="\d{5}"/> <xs:pattern value="\d{5}-\d{4}"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="CountryType"> <xs:restriction base="xs:string"> <xs:minLength value="1"/> <xs:maxLength value="64"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="CountyType"> <xs:restriction base="xs:string"> <xs:minLength value="1"/> <xs:maxLength value="32"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="PostCodeType"> <xs:restriction base="xs:string"> <xs:minLength value="1"/> <xs:maxLength value="12"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="ProvinceType"> <xs:restriction base="xs:string"> <xs:minLength value="2"/> <xs:maxLength value="2"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="NotesType"> <xs:restriction base="xs:string"> <xs:maxLength value="32767"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="UPCCodeType"> <xs:restriction base="xs:string"> <xs:minLength value="11"/> <xs:maxLength value="14"/> <xs:pattern value="\d{11}"/> <xs:pattern value="\d{12}"/> <xs:pattern value="\d{13}"/> <xs:pattern value="\d{14}"/> </xs:restriction> </xs:simpleType> </xs:schema>
PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveのパラメータと、このプロシージャに関連するエラーを説明します。
プロシージャDBMS_XMLSCHEMA.copyEvolveのシグネチャは、次のとおりです。
procedure copyEvolve(schemaURLs IN XDB$STRING_LIST_T,
newSchemas IN XMLSequenceType,
transforms IN XMLSequenceType := NULL,
preserveOldDocs IN BOOLEAN := FALSE,
mapTabName IN VARCHAR2 := NULL,
generateTables IN BOOLEAN := TRUE,
force IN BOOLEAN := FALSE,
schemaOwners IN XDB$STRING_LIST_T := NULL
parallelDegree IN PLS_INTEGER := 0,
options IN PLS_INTEGER := 0);
表20-1 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEのパラメータ
| パラメータ | 説明 |
|---|---|
|
拡張するXML SchemaのURLのVARRAY( |
|
新しいXML Schema文書( |
|
XML Schemaに基づく文書を新しいスキーマに準拠させるために、その文書に適用されるXSL文書( |
|
このパラメータが |
|
古い |
|
このパラメータのデフォルトは |
|
このパラメータが |
|
スキーマ所有者名のVARRAY。対応するURLと同じ順序で正確に指定します。 |
|
データのコピーの段階で、 |
|
その他のオプション。オプションは、 |
表20-2 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEに関連するエラー
| エラー番号とメッセージ | 原因 | 処置 |
|---|---|---|
30942 XML Schema Evolutionエラーです。スキーマ'<schema_url>'、表"<owner_name>.<table_name>"、列'<column_name>' |
指定のXML Schemaに準拠する指定の |
このエラーと後続の特定エラーに示されているスキーマ、表および列の情報に基づいて、適切な処置を実行します。 |
30943 XML Schema '<schema_url>'は、XML Schema '<schema_url>'に依存しています |
依存XML Schemaがまったく指定されていないか、またはスキーマが依存順序に指定されていません。つまり、スキーマS1がスキーマSに依存している場合、SはS1よりも前に出現する必要があります。 |
以前にスキーマのリストに指定されていないスキーマを挿入するか、またはスキーマの指定順序を修正します。その後、操作を再試行します。 |
30944 XML Schema '<schema_url>'(表<owner_name>.<table_name>、列'<column_name>')のロールバック中にエラーが発生しました |
指定のXML Schemaに準拠する指定の |
このエラーと後続の特定エラーに示されているスキーマ、表および列の情報に基づいて、適切な処置を実行します。 |
30945 マッピング表'<table_name>'を作成できませんでした |
XML Schema拡張中にマッピング表を作成できませんでした。このエラーの後に続くエラー・メッセージも参照してください。 |
指定した名前の表が存在しないことを確認してから、操作を再試行します。 |
30946 XML Schema Evolutionの警告: 一時表がクリーンアップされていません |
スキーマが拡張された後、一時表のクリーンアップでエラーが発生しました。スキーマの拡張は正常に終了しています。 |
一時表を削除する必要がある場合は、マッピング表を使用して一時表の名前を取得し、その一時表を削除します。 |
PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveの使用には、いくつかの制限が伴います。
拡張するスキーマに依存しているXMLType表に関連する索引、トリガー、制約、行レベルのセキュリティ(RLS)ポリシーおよび他のメタデータは保持されません。これらは、拡張後に再度作成する必要があります。
最上位要素名が変更される場合は、copyEvolveの実行終了後にいくつかの手順が必要です。詳細は、「最上位要素名の変更」を参照してください。
コピーに基づく拡張は、拡張するいずれかのスキーマに依存しているXMLType属性を保持するオブジェクト型の列を備えた表がある場合には、使用できません。たとえば、次の表を参照してください。
CREATE TYPE t1 AS OBJECT (n NUMBER, x XMLType); CREATE TABLE tab1 (e NUMBER, o t1) XMLType COLUMN o.x XMLSchema "s1.xsd" ELEMENT "Employee";
最上位要素Employeeを含むXML SchemaがURL s1.xsdに登録されていると仮定します。XMLType属性xを持つ列oを含む表tab1がXML Schemaに依存しているので、このXML Schemaは拡張できません。copyEvolveはXMLTypeオブジェクト属性を処理しないことに注意してください。そのような場合はエラーが発生します。
PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveを使用するための一般的なガイドラインと、特定のコンテキストに固有のガイドラインを示します。
次の一般的なガイドラインが、copyEvolveの使用に適用されます。この項の後半では、特定のコンテキストに適用される個別のガイドラインについても説明します。
ごみ箱をオフにして、削除した表がごみ箱にコピーされないようにします。
ALTER SESSION SET RECYCLEBIN=off;
拡張されるXML Schemaに依存するXML Schemaを識別します。次の問合せを使用して、依存XML SchemaのURLを取得できます。schema_to_be_evolvedは拡張されるスキーマで、owner_of_schema_to_be_evolvedはその所有者(データベース・ユーザー)です。
SELECT dxs.SCHEMA_URL, dxs.OWNER
FROM DBA_DEPENDENCIES dd, DBA_XML_SCHEMAS dxs
WHERE dd.REFERENCED_NAME = (SELECT INT_OBJNAME
FROM DBA_XML_SCHEMAS
WHERE SCHEMA_URL = schema_to_be_evolved
AND OWNER = owner_of_schema_to_be_evolved)
AND dxs.INT_OBJNAME = dd.NAME;
多くの場合、依存XML Schemaでの変更は不要です。ただし、依存XML Schemaの変更が必要な場合は、それらのXML Schemaの新しいバージョンも用意する必要があります。
既存のインスタンス・ドキュメントが新しいXML Schemaに準拠していない場合、インスタンス・ドキュメントへの適用時にXSLスタイル・シートを指定する必要があります。これにより新しいスキーマに準拠するようにインスタンス・ドキュメントが変換されます。手順2で識別したXML Schemaごとにこれを行う必要があります。この変換では、新しいXML Schemaのすべての最上位要素に準拠するようにドキュメントが処理されます。
プロシージャDBMS_XMLSCHEMA.copyEvolveをコールして、XML SchemaのURL、新しいスキーマおよび変換スタイルシートを指定します。
PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveでは、新しいスキーマの最上位要素は削除されていないこと、およびその名前が変更されていないことを前提としています。そのような変更がある場合、文書のバックアップ・コピーを使用できるように、パラメータgenerateTablesをFALSEに、パラメータpreserveOldDocsをTRUEに設定して、プロシージャcopyEvolveをコールします。
これらのパラメータ値を使用すると、新しい表は生成されず、古いドキュメント(バックアップ・コピー)を保持する一時表はプロシージャの最後に削除されません。その場合、古いドキュメントを適切な形式で格納し、一時表を削除できます。これらのパラメータの使用の詳細は、「COPYEVOLVEパラメータおよびエラー」を参照してください。
デフォルト表でない表では、コピーに基づく拡張では作成した仮想列は再作成されません。このような列が必要な場合、copyEvolveパラメータpreserveOldDocsをTRUEに設定して表を作成し、プロシージャcopyEvolveが完了した後に古いドキュメントをコピーします。
XML Schemaの拡張処理中は、拡張するXML Schemaとその依存を同時セッションで使用しないようにしてください。
拡張処理の開始時に、他の同時セッションがこのスキーマに対する共有ロックを保持していた場合、プロシージャDBMS_XMLSCHEMA.copyEvolveは、排他ロックを取得できるように、これらのセッションによるロックのリリースを待機します。ただし、このロックは、残りの処理を継続できるようにただちにリリースされます。
プロシージャDBMS_XMLSCHEMA.copyEvolveは、完全に成功するか、エラーが発生するかのいずれかです。エラーが発生した場合は、可能なかぎり多くの操作のロールバックを試行します。
XML Schemaの拡張には、多くのデータベースDDL文が含まれます。エラーが発生した場合、補正DDL文が実行され、その地点までに実行されたすべての手順を取り消します。古い表またはスキーマが削除された場合、再作成されますが、表、列、記憶域のプロパティおよび表や列に関連する補助構造(索引、トリガー、制約およびRLSポリシーなど)は失われます。
場合によっては、コピーに基づく拡張の操作はロールバックできません。たとえば、新規XML Schemaに関係のない理由で表の作成に失敗した場合は、ロールバックする方法がありません。
その理由には、不十分な権限による失敗などがあります。一時表はpreserveOldDocsがFALSEに設定されている場合にも削除されないため、データはリカバリできます。mapTabNameパラメータがNULLの場合、マッピング表はXDB$MAPTABの後に順序番号が続く名前となります。正確な表名は、次の問合せを使用して確認できます。
SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME LIKE 'XDB$MAPTAB%';
コピーに基づくXML Schemaの拡張を実行するには、いくつかのデータベース権限が必要になる場合があります。
コピーに基づくXML Schemaの拡張にはSQLデータ型の削除または作成が伴う場合があるため、DROP TYPE、CREATE TYPEおよびALTER TYPEなどの型に関連する権限が必要です。スキーマを拡張するには、拡張に関係するXML Schemaを削除および登録する権限が必要です。拡張するスキーマに準拠するXMLType表に対するすべての権限が必要です。XMLType列については、対応する表に対するALTER TABLE権限が必要です。他のデータベース・スキーマ内にXML Schemaに基づくXMLType表または列が存在する場合は、次のような権限が必要です。
CREATE ANY TABLE
CREATE ANY INDEX
SELECT ANY TABLE
READ ANY TABLE
UPDATE ANY TABLE
INSERT ANY TABLE
DELETE ANY TABLE
DROP ANY TABLE
ALTER ANY TABLE
DROP ANY INDEX
他のデータベース・スキーマに属するXML Schemaに基づくXMLType表または列がある場合は、これらのすべての権限をデータベース・スキーマ所有者に付与しなくてすむように、データベース管理者が拡張を実行することをお薦めします。
登録済XML Schemaを変更した後は、そのXML Schemaを使用する既存のXMLインスタンス・ドキュメントも更新する必要があります。更新するには、各インスタンス・ドキュメントにXSLTスタイルシートを適用します。このスタイルシートは、古いXML Schemaと新しいXML Schemaの差分を表します。
例20-2はファイルevolvePurchaseOrder.xsl内のXSLTスタイルシートを示しています。これによって、古いXML Schemaを使用していた既存の発注書が新しいXML Schemaを使用するように変換されます。
例20-2 evolvePurchaseOrder.xsl: インスタンス・ドキュメントを更新するXSLTスタイルシート
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="/PurchaseOrder">
<PurchaseOrder>
<xsl:attribute name="xsi:noNamespaceSchemaLocation">
http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd
</xsl:attribute>
<xsl:for-each select="Reference">
<xsl:attribute name="Reference">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:variable name="V264_394" select="'2004-01-01T12:00:00.000000-08:00'"/>
<xsl:attribute name="DateCreated">
<xsl:value-of select="$V264_394"/>
</xsl:attribute>
<xsl:for-each select="Actions">
<Actions>
<xsl:for-each select="Action">
<Action>
<xsl:for-each select="User">
<User>
<xsl:value-of select="."/>
</User>
</xsl:for-each>
<xsl:for-each select="Date">
<Date>
<xsl:value-of select="."/>
</Date>
</xsl:for-each>
</Action>
</xsl:for-each>
</Actions>
</xsl:for-each>
<xsl:for-each select="Reject">
<Reject>
<xsl:for-each select="User">
<User>
<xsl:value-of select="."/>
</User>
</xsl:for-each>
<xsl:for-each select="Date">
<Date>
<xsl:value-of select="."/>
</Date>
</xsl:for-each>
<xsl:for-each select="Comments">
<Comments>
<xsl:value-of select="."/>
</Comments>
</xsl:for-each>
</Reject>
</xsl:for-each>
<xsl:for-each select="Requestor">
<Requestor>
<xsl:value-of select="."/>
</Requestor>
</xsl:for-each>
<xsl:for-each select="User">
<User>
<xsl:value-of select="."/>
</User>
</xsl:for-each>
<xsl:for-each select="CostCenter">
<CostCenter>
<xsl:value-of select="."/>
</CostCenter>
</xsl:for-each>
<ShippingInstructions>
<xsl:for-each select="ShippingInstructions">
<xsl:for-each select="name">
<name>
<xsl:value-of select="."/>
</name>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="ShippingInstructions">
<xsl:for-each select="address">
<fullAddress>
<xsl:value-of select="."/>
</fullAddress>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="ShippingInstructions">
<xsl:for-each select="telephone">
<telephone>
<xsl:value-of select="."/>
</telephone>
</xsl:for-each>
</xsl:for-each>
</ShippingInstructions>
<xsl:for-each select="SpecialInstructions">
<SpecialInstructions>
<xsl:value-of select="."/>
</SpecialInstructions>
</xsl:for-each>
<xsl:for-each select="LineItems">
<LineItems>
<xsl:for-each select="LineItem">
<xsl:variable name="V22" select="."/>
<LineItem>
<xsl:for-each select="@ItemNumber">
<xsl:attribute name="ItemNumber">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="$V22/Part">
<xsl:variable name="V24" select="."/>
<xsl:for-each select="@Id">
<Part>
<xsl:for-each select="$V22/Description">
<xsl:attribute name="Description">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="$V24/@UnitPrice">
<xsl:attribute name="UnitCost">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:value-of select="."/>
</Part>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="$V22/Part">
<xsl:for-each select="@Quantity">
<Quantity>
<xsl:value-of select="."/>
</Quantity>
</xsl:for-each>
</xsl:for-each>
</LineItem>
</xsl:for-each>
</LineItems>
</xsl:for-each>
</PurchaseOrder>
</xsl:template>
</xsl:stylesheet>
PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveを使用してXML Schemaを更新する例をいくつか示します。(プロシージャを使用する前に、必ず、すべての登録済XML Schemaとそれを参照するXML文書をバックアップしてください。)
例20-3では、修正されたXML Schemaおよび拡張XSLスタイルシートをOracle XML DBリポジトリにロードします。
例20-4は、プロシージャDBMS_XMLSCHEMA.copyEvolveを使用し、XSLTスタイルシートevolvePurchaseOrder.xslによってXML Schema purchaseOrder.xsdをrevisedPurchaseOrder.xsdに拡張する方法を示しています。
プロシージャDBMS_XMLSCHEMA.copyEvolveは、既存のインスタンス・ドキュメントの妥当性を保持しながら、登録されているXML Schemaを拡張します。
注意:
プロシージャDBMS_XMLSCHEMA.copyEvolveを実行する前に、すべての登録済XML Schemaとそれに準拠するすべてのXML文書を必ずバックアップしてください。プロシージャcopyEvolveでは、登録済のXML Schemaに準拠するすべての文書が削除されます。
まず、プロシージャcopyEvolveがXML Schemaに基づくXMLType表および列のデータを一時表にコピーします。次に元の表および列を削除し、古いXML Schemaを削除します。新しいXML Schemaを登録した後、XMLType表および列を作成し、それにデータを移入しますが(パラメータGENTABLESがFALSEの場合を除く)、索引、制約、トリガーおよび行レベル・セキュリティ(RLS)ポリシーなどの補助構造は作成しません。プロシージャcopyEvolveは次のように表および列を作成します。
新しいスキーマの登録時に、デフォルトの表を作成します。
次の書式の文で、デフォルト表ではない表を作成します。
CREATE TABLE table_name OF XMLType OID 'oid' XMLSCHEMA schema_url ELEMENT element_name
OIDは、削除前の元の表のOIDです。
次の書式の文を使用して、XMLType列を追加します。
ALTER TABLE table_name ADD (column_name XMLType) XMLType COLUMN column_name XMLSCHEMA schema_url ELEMENT element_name
対応する古いスキーマの登録で型が生成されていた場合は、新しいXML Schemaの登録時に型が生成されます。拡張前にグローバルだったXML Schemaは、拡張後もグローバルになります。同様に、拡張前にXML Schemaがローカルだった場合は、拡張後もローカル(同じユーザーが所有)になります。パラメータpreserveOldDocsをTRUEに設定すると、古いドキュメントを含む一時表を保持できます。すべての一時表は現行ユーザーのデータベース・スキーマ内に作成されます。XMLType表には、表20-3で示すような列が一時表に存在します。
表20-3 XML Schemaの拡張: XMLType表の一時表の列
| 名前 | 型 | コメント |
|---|---|---|
|
|
|
|
|
古い表で対応する行の |
|
|
この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行の |
|
|
この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行の |
XMLType列には、表20-4で示すような列が一時表に存在します。
表20-4 XML Schemaの拡張: XMLType列の一時表の列
| 名前 | 型 | コメント |
|---|---|---|
|
|
|
|
|
この列が含まれる表の対応する行の |
プロシージャCopyEvolveは、古い表または列名から、mapTabNameパラメータで指定された個別の表に対応する一時表名へのマッピングに関する情報を格納します。preserveOldDocsがTRUEの場合、mapTabNameパラメータは、NULL以外の値であり、かつ現行ユーザーのスキーマに存在しない表名である必要があります。マッピング表の各行には、古い表または列の1つに関する情報が含まれます。表20-5に、マッピング表の列を示します。
表20-5 プロシージャCOPYEVOLVEのマッピング表
| 列名 | 列の型 | コメント |
|---|---|---|
|
|
この表または列が一致するスキーマのURL。 |
|
|
スキーマの所有者。 |
|
|
この表または列が一致する要素。 |
|
|
表の修飾名( |
|
|
表の |
|
|
列の名前( |
|
|
この表または列のデータを保持する一時表の名前。 |
GENTABLESパラメータにFALSEを指定することで、新しいXML Schemaの登録後、表または列の生成を回避できます。GENTABLESがFALSEの場合は、パラメータPRESERVEOLDDOCSをTRUEにし、パラメータMAPTABNAMEをNULL以外の値にする必要があります。これによって、古い表のデータが消失しません。これは、「COPYEVOLVEパラメータおよびエラー」の説明のとおり、プロシージャで表を作成する必要がない場合に役立ちます。
デフォルトでは、すべてのXML Schemaは、現行ユーザーが所有していると想定しています。そうでない場合は、schemaOwnersパラメータで各XML Schemaの所有者を指定する必要があります。
関連項目:
ALTER TABLEの完全な説明は、『Oracle Database SQL言語リファレンス』を参照してください。
例20-3 修正されたXML SchemaおよびXSLTスタイルシートのロード
DECLARE
res BOOLEAN;
BEGIN
res := DBMS_XDB_REPOS.createResource( -- Load revised XML schema
'/source/schemas/poSource/revisedPurchaseOrder.xsd',
bfilename('XMLDIR', 'revisedPurchaseOrder.xsd'),
nls_charset_id('AL32UTF8'));
res := DBMS_XDB_REPOS.createResource( -- Load revised XSL stylesheet
'/source/schemas/poSource/evolvePurchaseOrder.xsl',
bfilename('XMLDIR', 'evolvePurchaseOrder.xsl'),
nls_charset_id('AL32UTF8'));
END;/
例20-4 DBMS_XMLSCHEMA.COPYEVOLVEを使用したXML Schemaの更新
BEGIN
DBMS_XMLSCHEMA.copyEvolve(
xdb$string_list_t('http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd'),
XMLSequenceType(XDBURIType('/source/schemas/poSource/revisedPurchaseOrder.xsd').getXML()),
XMLSequenceType(XDBURIType('/source/schemas/poSource/evolvePurchaseOrder.xsl').getXML()));
END;
SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[1]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) line_item
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2003030912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");
LINE_ITEM
------------------------------------------------------------------------------
<LineItem ItemNumber="1">
<Part Description="A Night to Remember" UnitCost="39.95">715515009058</Part>
<Quantity>2</Quantity>
</LineItem>
同じ問合せにより、スキーマの拡張前に次の結果が生成されます。
LINE_ITEM ---------------------------------------------------------- <LineItem ItemNumber="1"> <Description>A Night to Remember</Description> <Part Id="715515009058" UnitPrice="39.95" Quantity="2"/> </LineItem>
インプレースのXML Schemaの拡張では、既存データをコピー、削除、再挿入せずにXML Schemaを変更します。そのため、インプレースの拡張は、コピーに基づく拡張よりも高速に行うことができます。ただし、インプレースの拡張には、コピーに基づく拡張にはない制限がいくつかあります。
プロシージャ DBMS_XMLSCHEMA.inPlaceEvolveを使用して、インプレースの拡張を実行します。このプロシージャを使用して、XML Schema差分ドキュメントを指定することにより、既存のXML Schemaに加えられた変更を識別し、オプションで、拡張プロセスに適用されるフラグを指定します。
インプレースの拡張では、diffXML文書で指定された変更を適用することによる新しいバージョンのXML Schemaの構成、新しいXML Schemaの検証(XML Schemaの場合はXML Schemaに対して)、DDL文の構成による、XML Schemaに関連付けられたXMLインスタンス・ドキュメントを格納するのに使用されるディスク構造の拡張、それらのDDL文の実行、および旧バージョンのXML Schemaの新バージョンへの置換が、この順序で実行されます。新しいバージョンのXML Schemaが妥当なスキーマでなかった場合、インプレースの拡張は失敗します。
インプレースのXML Schemaの拡張ではデータをコピーしないため、XML Schemaへの任意の変更は許可されません。インプレース拡張を使用する際の主要な制限は一般に、指定されたXML Schemaが、下位互換にのみインプレース拡張できることという要件として記述できます。
インプレースの拡張でサポートされている変更の完全なリストは、インプレースのXML Schema拡張でサポートされる操作を参照してください。
つまり、下位互換とは、指定のXML Schemaに対して検証される可能性のあるすべてのインスタンス・ドキュメントは、そのXML Schemaの将来の(拡張)バージョンでも同様に検証される必要があります。これは既存のインスタンス・ドキュメントに限らず、すべての可能な準拠インスタンス・ドキュメントに適用されます。バイナリXMLとして格納されたXMLデータの場合、下位互換性は、バイナリXML処理に影響を与えるXML Schema注釈は拡張中に変更できないことも意味します。下位互換性の詳細は、下位互換性の制約で説明します。
この一般的な下位互換性制限に加え、インプレースの拡張には他の制約もあります。それについては項「インプレース拡張のその他の制限」で説明します。
説明するインプレースXML Schemaの拡張の制限により、拡張されたスキーマの下位互換性が保証されるため、以前のXML Schemaを満足させる可能なインスタンス・ドキュメントはすべて、新しいスキーマを満足させます。
XML Schemaへの一定の変更は、関連付けられるディスク上のインスタンス・ドキュメントのレイアウトが変更されるため許可されていません。これはオブジェクト・リレーショナル記憶域の場合と同様、記憶域のレイヤーがXML Schemaから導出された情報と密に統合されている場合に一般的な状況です。
そのような例の1つは、オブジェクト・リレーショナル記憶域のマッピングとして登録されたXML Schemaで、1つの複合型を2つの複合型に分割することで拡張されます。例20-5では、複合型ShippingInstructionsTypeが2つの複合型Person-NameとContact-Infoに分割され、ShippingInstructionsType複合型は削除されます。
このXML Schemaに関連付けられているインスタンス・ドキュメントがないため、データのコピーが不要な場合でも、今後のインスタンス・ドキュメントに対応するために既存の表のレイアウトを変更する必要があります。
例20-5 1つの複合型の2つの複合型への分割
このコードの抜粋は、元のShippingInstructionsType型と新規のPerson-Name型およびContact-Info型の定義を示しています。
<complexType name="ShippingInstructionsType">
<sequence>
<element name="name" type="NameType" minOccurs="0"/>
<element name="address" type="AddressType" minOccurs="0"/>
<element name="telephone" type="TelephoneType" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="Person-Name">
<sequence>
<element name="name" type="NameType" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="Contact-Info">
<sequence>
<element name="address" type="AddressType" minOccurs="0"/>
<element name="telephone" type="TelephoneType" minOccurs="0"/>
</sequence>
</complexType>
XMLインスタンス・ドキュメントのDOM再現性に影響を及ぼすような方法では、XML Schema要素の再順序付けにインプレースの拡張を使用できません。たとえば、複合型定義での<sequence>要素内の要素の順序は変更できません。
具体的には、複合型ShippingInstructionsTypeでその子要素をname、address、telephoneの順にする必要がある場合、順序をname、telephone、addressに変更するためにインプレースの拡張は使用できません。
コレクションから非コレクションへの変更に、インプレースの拡張は使用できません。例としては、1より大きいmaxOccursから1であるmaxOccursへの変更が考えられます。そのため、削除でコレクションから非コレクションへの拡張が必要となる場合、インプレースの拡張では複合型から要素は削除できません。
インプレースのスキーマ拡張でサポートされるいくつかの操作について説明します。これらの一部は、指定される特定のコンテキストでは許可されません。
複合型またはグループへのオプション要素の追加:常に許可されます。たとえば、複合型定義へのオプション要素shipmethodの追加を次に示します。
<xs:complexType name="ShippingInstructionsType">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0"/>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0"/>
<xs:element name = "shipmethod" type = "xs:string" minOccurs = "0"/>
</xs:sequence>
</xs:complexType>
複合型または属性グループへのオプション属性の追加:常に許可されます。たとえば、複合型定義へのオプション属性shipbydateの追加を次に示します。
<xs:complexType name="ShippingInstructionsType">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0"/>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="shipbydate" type="DateType" use="optional"/>
</xs:complexType>
単純型から単純な内容を含む複合型への変換:記憶域モデルがバイナリXMLの場合のみサポートされます。
既存のmaxLength要素のvalue属性の変更:常に許可されます。現在の値より大きい値に変更することはできますが、小さい値には変更できません。
enumeration値の追加:enumeration値は、enumerationリストの末尾にのみ新たに追加できます。
グローバル要素の追加:常に許可されます。たとえば、スキーマ定義へのグローバル要素PurchaseOrderCommentの追加を次に示します。
<xs:schema ...>
...
<xs:element name="PurchaseOrderComment" type="string" xdb:defaultTable=""/>
..
</xs:schema>
グローバル属性の追加:常に許可されます。
グローバル複合型の追加または削除:常に許可されます。たとえば、スキーマ定義へのグローバル複合型ComplexAddressTypeの追加を次に示します。
<xs:schema ...>
....
<xs:complexType name="ComplexAddressType">
<xs:sequence>
<xs:element name="street" type="string"/>
<xs:element name="city" type="string"/>
<xs:element ref="zip" type="positiveInteger"/>
<xs:element name="country" type="string"/>
</xs:sequence>
</xs:complexType>
...
</xs:schema>
グローバル単純型の追加または削除:常に許可されます。
minOccurs属性値の変更: minOccurs値は減少のみ許可されます。
maxOccurs属性値の変更: maxOccursの値はバイナリXML形式で格納されるデータにかぎり、増加のみ許可されます。つまり、オブジェクト・リレーショナル形式で格納されているデータのmaxOccurs属性は変更できません。
グローバル・グループまたはattributeGroupの追加または削除: 常に許可されます。たとえば、型定義へのInstructionsグループの追加を次に示します。
<xsd:schema ...> ... <xsd:group name="Instructions"> <xsd:sequence> <xsd:element name="ShippingInstructions" type="ShippingInstructionsType"/> <xsd:element name="SpecialInstructions" type=" SpecialInstructionsType"/> </xsd:sequence> </xsd:group> ... </xsd:schema>
xdb:defaultTable属性値の変更:常に許可されます。xdb名前空間内の他の属性に対する変更は許可されません。
コメントまたは処理命令の追加、変更、削除:常に許可されます。
インプレースXML Schemaの拡張に適用されるガイドラインを示します。(インプレースのスキーマ拡張を実行する前に、必ずデータをバックアップしてください。)
インプレースXML Schemaの拡張を実行する前に、次のことを行います。
拡張されるXML Schemaのすべての既存データ(インスタンス・ドキュメント)をバックアップします。
注意:
結果が想定外になる場合に備えて、インプレースのXML Schema拡張を実行する前に、必ずデータをバックアップしてください。インプレース拡張の後は、ロールバックできません。拡張時にエラーが発生した場合や、大きな失敗があり操作全体の再実行が必要な場合、元のデータのバックアップ・コピーに戻せる必要があります。
トレースのみを使用してドライ・ランを実行します。実際にXML Schemaが拡張されたり、インスタンス文書が更新されたりすることなく、拡張時に実行される更新操作のトレースが生成されます。これを実行するには、flagパラメータ値をINPLACE_TRACEにのみ設定します。INPLACE_EVOLVEは使用しないでください。
予行演習を実行した後でトレース・ファイルをチェックし、リストされたDDL操作が本当に意図したとおりであることを確認します。
インプレースXML Schemaの拡張を実行した後で、次のことを行います。
データをキャッシュするクライアントを使用してデータベースにアクセスしている場合、または当てはまるかどうか不明な場合は、クライアントを再起動します。そうしないと、引き続き拡張前のバージョンのXML Schemaがローカルに使用され、予想外の結果になる可能性があります。
関連項目:
トレース・ファイルの使用の詳細は、『Oracle Database管理者ガイド』を参照してください。
PL/SQLプロシージャDBMS_XMLSCHEMA.inPlaceEvolveのパラメータと、このプロシージャに関連するエラーを説明します。
プロシージャDBMS_XMLSCHEMA.inPlaceEvolveのシグネチャは、次のとおりです。
procedure inPlaceEvolve(schemaURL IN VARCHAR2,
diffXML IN XMLType,
flags IN NUMBER);
表20-6に、各パラメータについて説明します。
表20-6 プロシージャDBMS_XMLSCHEMA.INPLACEEVOLVEのパラメータ
| パラメータ | 説明 |
|---|---|
|
拡張するXML SchemaのURL( |
|
|
|
プロシージャの動作を制御するビット・マスク。次に示すこのマスクのビット値を個別に設定し、それらを合計し、全体の影響を定義できます。デフォルトの
つまり、それぞれのビットがXML Schemaを構成、検証し、インスタンス・ドキュメントの基礎となるディスク構造の拡張に必要な手順を決定します。また、次の点があげられます。
|
プロシージャDBMS_XMLSCHEMA.inPlaceEvolveでは、次の場合にエラーが発生します。
XPath式が無効であるか、構文が正しいもののXML Schema内のノードをターゲットにしていない場合。
diffXML文書がxdiff XML Schemaに準拠していない場合。
変更によってXML Schemaが無効になるか、整形式でなくなる場合。
生成されたDDL文(CREATE TYPE、ALTER TYPEなど)の実行時に問題が発生した場合。
XMLType表に関連する索引オブジェクトが不安定な状態にあり、その原因がパーティション管理操作の可能性がある場合。
プロシージャDBMS_XMLSCHEMA.inPlaceEvolveのパラメータdiffXMLの値は、インプレースの拡張においてXML Schemaに適用される変更を指定したXMLTypeインスタンスです。このdiffXML文書には、古いXML Schemaと新規の(拡張の結果となる予定の)XML Schemaとの間の変更を示す一連の操作が含まれます。
diffXML文書で指定された変更は、この順序で適用されます。
diffXMLパラメータで使用されるXML文書を作成する必要があります。これを行うには、次のいずれかの方法を実行します。
XMLDiff JavaBean(oracle.xml.differ.XMLDiff)
xmldiffコマンドライン・ユーティリティ
SQL関数XMLDiff
diffXML文書はxdiff XML Schemaに準拠している必要があります。
この項の後半では、xdiff XML Schemaに準拠するドキュメント内の操作例を示します。
関連項目:
XMLDiff JavaBeansの使用に関する詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。
xmldiffコマンドライン・ユーティリティに関する詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。
SQL関数XMLDiffに関する詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
プロシージャDBMS_XMLSCHEMA.inPlaceEvolveのためにdiffXML文書で指定された操作について説明します。xdiff XML Schemaに準拠したXML文書の例を示します。
複合型への新規属性の追加、グループへの新規要素の追加など、サポートされているほとんどの変更において、<append-node>要素が使用されています。
<insert-node-before>要素は、指定された型のノードを特定のノードの前に挿入する必要があることを指定します。xpath属性は、特定のノードの位置を指定し、node-type属性は挿入されるノードの型を指定します。挿入されるノードは、<content>子要素で指定されます。<insert-node-before>要素は、主にコメントの挿入、命令の処理、およびannotation要素の変更と追加に使用されます。
<delete-node>要素は、特定のXPath(xpath属性で指定)のあるノードをそのすべての子とともに削除することを指定しています。たとえば、この要素はコメントやannotation要素の削除に使用できます。また、この要素を<append-node>または<insert-node-before>とともに使用し、既存のノードを変更できます。
例20-6は、次の変更を指定するdiffXMLパラメータのXML文書を示しています。
複合型PartTypeの削除。
最大長28での複合型PartTypeの追加。
ShippingInstructions要素の前へのコメントの追加。
必須要素shipmethodのShippingInstructions要素への追加。
例20-6 diffXMLパラメータ・ドキュメント
<xd:xdiff xmlns="http://www.w3c.org/2001/XMLSchema"
xmlns:xd="http://xmlns.oracle.com/xdb/xdiff.xsd"
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-Instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/xdiff.xsd
http://xmlns.oracle.com/xdb/xdiff.xsd">
<xd:delete-node xpath="/schema/complexType[@name="e;PartType"e;]//maxLength/>
<xd:append-node
parent-xpath = "/schema/complexType[@name="e;PartType"e;]//restriction"
node-type = "element">
<xd:content>
<xs:maxLength value = "28"/>
</xd:content>
</xd:append-node>
<xd:insert-node-before
xpath="/schema/complexType[@name ="e;ShippingInstructionsType"e;]/sequence"
node-type="comment">
<xd:content>
<!-- A type representing instructions for shipping -->
</xd:content>
</xd:insert-node-before>
<xd:append-node
parent-xpath="/schema/complexType[@name="e;ShippingInstructionsType"e;]/sequence"
node-type="element">
<xd:content>
<xs:element name = "shipmethod" type = "xs:string" minOccurs = "1"/>
</xd:content>
</xd:append-node>
</xd:xdiff>