この章では、XML SchemaをOracle XML DBに登録した後、更新する方法について説明します。XML Schemaの拡張とは、登録したXML Schemaを更新する処理です。
この章の内容は次のとおりです。
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プロシージャがそれぞれ用意されています。この章のそれぞれの項では、各プロシージャの使用方法や、スキーマの拡張に関連する方法のガイドラインを説明しています。
コピーに基づくXML Schemaの拡張は、PL/SQLパッケージDBMS_XMLSCHEMA
のプロシージャcopyEvolve
を使用して実行します。プロシージャcopyEvolve
は、既存のインスタンス・ドキュメントをバックアップのために一時XMLType
表にコピーし、古いバージョンのXML Schemaを削除します(また、関連付けられているインスタンス・ドキュメントも削除します)。次に、新規バージョンを登録し、バックアップしたインスタンス・ドキュメントを新規XMLType
表にコピーします。問題が発生した場合、バックアップされたコピーはリストアされます。詳細は、「プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック」を参照してください。
プロシージャcopyEvolve
を使用すると、既存のXMLインスタンス・ドキュメントの有効性を保持しながら、登録されたXML Schemaを拡張できます。
例9-1は、例3-8の発注書XML Schemaの修正バージョンのリストの一部を示しています。完全な修正スキーマのリストは、例A-2を参照してください。この例では、太字のテキストが新規部分、または元のスキーマと異なる部分です。
例9-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>
プロシージャ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);
表9-1に、各パラメータについて説明します。表9-2に、このプロシージャに関連するエラーについて説明します。
表9-1 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEのパラメータ
パラメータ | 説明 |
---|---|
|
拡張するXML SchemaのURLのVARRAY( |
|
新しいXML Schema文書( |
|
XML Schemaに基づく文書を新しいスキーマに準拠させるために、その文書に適用されるXSL文書( |
|
このパラメータが |
|
古い |
|
デフォルトでは、このパラメータは |
|
このパラメータが |
|
スキーマ所有者名のVARRAY。対応するURLと同じ順序で正確に指定します。 |
|
データのコピーの段階で、 |
|
その他のオプションです。オプションは |
表9-2 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEに関連するエラー
エラー番号とメッセージ | 原因 | 処置 |
---|---|---|
30942 XML Schema Evolutionエラーです。スキーマ'<schema_url>'、"<owner_name>.<table_name>"、列'<column_name>' |
指定のスキーマに準拠する指定の |
このエラーと後続の特定エラーに示されているスキーマ、表および列の情報に基づいて、適切な処置を実行します。 |
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>')のロールバック中にエラーが発生しました |
指定のスキーマに準拠する指定の |
このエラーと後続の特定エラーに示されているスキーマ、表および列の情報に基づいて、適切な処置を実行します。 |
30945 マッピング表'<table_name>'を作成できませんでした |
XML Schema拡張中にマッピング表を作成できませんでした。このエラーの後に続くエラー・メッセージも参照してください。 |
指定した名前の表が存在しないことを確認してから、操作を再試行します。 |
30946 XML Schema Evolutionの警告: 一時表がクリーンアップされていません |
スキーマが拡張された後、一時表のクリーンアップでエラーが発生しました。スキーマの拡張は正常に終了しています。 |
一時表を削除する必要がある場合は、マッピング表を使用して一時表の名前を取得し、その一時表を削除します。 |
プロシージャ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
を持つ表tab1
の列o
がこのXML Schemaに依存しているため、このXML Schemaを拡張することはできません。copyEvolve
はXMLType
オブジェクト属性を処理しませんが、このような場合はエラーが発生します。
次は、プロシージャDBMS_XMLSCHEMA.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、新しいスキーマおよび変換スタイルシートを指定します。
プロシージャDBMS_XMLSCHEMA.copyEvolve
では、最上位要素は削除されず、新しいXML Schemaでも最上位要素名は変更されていないことを想定しています。新しいXML Schemaでこのような変更がある場合は、generateTables
パラメータをFALSE
、preserveOldDocs
パラメータをTRUE
に設定して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の拡張では、データ型の削除や作成が必要な場合があります。したがって、DROP TYPE
、CREATE TYPE
およびALTER TYPE
などの型に関連する権限が必要です。
スキーマを拡張するには、拡張に関係するXML Schemaを削除および登録する権限が必要です。拡張するスキーマに準拠するXMLType
表に対するすべての権限が必要です。XMLType
列については、対応する表に対するALTER TABLE
権限が必要です。他のデータベース・スキーマ内にXML Schemaに基づくXMLType
表または列が存在する場合は、次のような権限が必要です。
CREATE ANY TABLE
CREATE ANY INDEX
SELECT ANY TABLE
UPDATE ANY TABLE
INSERT ANY TABLE
DELETE ANY TABLE
DROP ANY TABLE
ALTER ANY TABLE
DROP ANY INDEX
他のデータベース・スキーマに属するXML Schemaに基づくXMLType
表または列がある場合は、これらのすべての権限をデータベース・スキーマ所有者に付与しなくてすむように、DBAが拡張を実行することをお薦めします。
登録済のXML Schemaを変更した後は、そのスキーマを使用していた既存のXMLインスタンス・ドキュメントも更新する必要があります。更新するには、各インスタンス・ドキュメントにXSLTスタイルシートを適用します。このスタイルシートは、古いスキーマと新しいスキーマの差分を表します。
例9-2はファイルevolvePurchaseOrder.xsl
内のスタイルシートです。これによって、古いスキーマを使用していた既存の発注書が新しいスキーマを使用するように変換されます。
例9-2 evolvePurchaseOrder.xsl: インスタンス・ドキュメントを更新するスタイルシート
<?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>
例9-3では、修正されたXML Schemaおよび拡張XSLスタイルシートをOracle XML DBリポジトリにロードします。
例9-3 修正されたXML SchemaおよびXSLスタイルシートのロード
DECLARE res BOOLEAN; BEGIN res := DBMS_XDB.createResource( -- Load revised XML schema '/source/schemas/poSource/revisedPurchaseOrder.xsd', bfilename('XMLDIR', 'revisedPurchaseOrder.xsd'), nls_charset_id('AL32UTF8')); res := DBMS_XDB.createResource( -- Load revised XSL style sheet '/source/schemas/poSource/evolvePurchaseOrder.xsl', bfilename('XMLDIR', 'evolvePurchaseOrder.xsl'), nls_charset_id('AL32UTF8')); END;/
例9-4は、プロシージャDBMS_XMLSCHEMA.copyEvolve
を使用し、XSLスタイルシートevolvePurchaseOrder.xsl
によってXML Schema purchaseOrder.xsd
をrevisedPurchaseOrder.xsd
に拡張する方法を示しています。
例9-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 extract(object_value, '/PurchaseOrder/LineItems/LineItem[1]') LINE_ITEM FROM purchaseorder WHERE existsNode(object_value, '/PurchaseOrder[@Reference="SBELL-2003030912333601PDT"]') = 1 / 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>
プロシージャDBMS_XMLSCHEMA.copyEvolve
は、既存のインスタンス・ドキュメントの妥当性を保持しながら、登録されているXML Schemaを拡張します。
注意: プロシージャDBMS_XMLSCHEMA.copyEvolve の実行前には必ず、登録されているすべてのXML Schemaと、その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
表には、表9-3で示すような列が一時表に存在します。
表9-3 XML Schemaの拡張: XMLType表の一時表の列
Name | 型 | コメント |
---|---|---|
|
|
|
|
|
古い表で対応する行の |
|
|
この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行の |
|
|
この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行の |
XMLType
列には、表9-4で示すような列が一時表に存在します。
表9-4 XML Schemaの拡張: XMLType列の一時表の列
Name | 型 | コメント |
---|---|---|
|
|
|
|
|
この列が含まれる表の対応する行の |
プロシージャCopyEvolve
は、古い表または列名から、mapTabName
パラメータで指定された個別の表に対応する一時表名へのマッピングに関する情報を格納します。preserveOldDocs
がTRUE
の場合、mapTabName
パラメータは、NULL
以外の値であり、かつ現行ユーザーのスキーマに存在しない表名である必要があります。マッピング表の各行には、古い表または列の1つに関する情報が含まれます。表9-5に、マッピング表の列を示します。
表9-5 プロシージャcopyEvolveのマッピング表
列名 | 列の型 | コメント |
---|---|---|
|
|
この表または列が一致するスキーマのURL。 |
|
|
スキーマの所有者。 |
|
|
この表または列が一致する要素。 |
|
|
表の修飾名( |
|
|
表の |
|
|
列の名前( |
|
|
この表または列のデータを保持する一時表の名前。 |
GENTABLES
パラメータにFALSE
を指定することで、新しいXML Schemaの登録後、表または列の生成を回避できます。GENTABLES
がFALSE
の場合は、パラメータPRESERVEOLDDOCS
をTRUE
にし、パラメータMAPTABNAME
をNULL
以外の値にする必要があります。これによって、古い表のデータが消失しません。これは、「copyEvolveパラメータおよびエラー」の説明のとおり、プロシージャで表を作成する必要がない場合に役立ちます。
デフォルトでは、すべてのXML Schemaは、現行ユーザーが所有していると想定しています。そうでない場合は、schemaOwners
パラメータで各XML Schemaの所有者を指定する必要があります。
関連項目: ALTER TABLE の完全な説明は、『Oracle Database SQL言語リファレンス』を参照してください。 |
インプレースの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拡張でサポートされる操作」を参照してください。
インプレース拡張を使用する際の主要な制限は一般に、指定されたXML Schemaが、下位互換にのみインプレース拡張できることという要件として記述できます。つまり、指定のXML Schemaに対して検証される可能性のあるすべてのインスタンス・ドキュメントは、そのXML Schemaの将来の(拡張)バージョンでも同様に検証される必要があります。これが既存のインスタンス・ドキュメントにのみ適用されるわけではないことに注意してください。準拠するすべての可能なインスタンス・ドキュメントに適用されます。バイナリXML形式で格納されるXMLデータの場合、下位互換性は、バイナリXMLの処理に影響を与えるすべてのXML Schema注釈が拡張時に変更されてはならないことも意味します。下位互換性の詳細は、項「下位互換性の制約」で説明します。
この一般的な下位互換性制限に加え、インプレースの拡張には他の制約もあります。それについては項「インプレース拡張のその他の制限」で説明します。
この項で説明する制約は、拡張されたXML Schemaの下位互換性を保証するため、以前のXML Schemaを満足させる可能なインスタンス・ドキュメントはすべて、新しいスキーマを満足させます。
XML Schemaへの一定の変更は、関連付けられるディスク上のインスタンス・ドキュメントのレイアウトが変更されるため許可されていません。これはオブジェクト・リレーショナル記憶域の場合と同様、記憶域のレイヤーがXML Schemaから導出された情報と密に統合されている場合に一般的な状況です。
たとえば、XML Schemaがオブジェクト・リレーショナル記憶域のマッピングとして登録される場合などです。このスキーマは、1つの複合型を2つの複合型に分割することによって拡張されます。例9-5では、複合型ShippingInstructionsType
が2つの複合型Person-Name
とContact-Info
に分割され、複合型ShippingInstructionsType
は削除されます。
例9-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 Schemaに関連付けられているインスタンス・ドキュメントがないため、データのコピーが不要な場合でも、今後のインスタンス・ドキュメントに対応するために既存の表のレイアウトを変更する必要があります。
この項では、インプレースのスキーマ拡張においてサポートされる操作を説明します。サポートされる操作のリストは、完全ではない場合があります。ここにリストした一部の操作は、特定のコンテキストで許可されません。それらのコンテキストは指定されています。特に、ここで説明する一部の操作は、バイナリXMLとともに使用されるXML Schemaに対しては許可されません。
複合型またはグループへのオプション要素の追加: 常に許可されます。たとえば、複合型定義へのオプション要素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
属性は変更できません。
グローバル・グループまたは属性グループの追加または削除: 常に許可されます。たとえば、型定義への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管理者ガイド』を参照してください。 |
プロシージャDBMS_XMLSCHEMA.inPlaceEvolve
のシグネチャは、次のとおりです。
procedure inPlaceEvolve(schemaURL IN VARCHAR2, diffXML IN XMLType, flags IN NUMBER);
表9-6に、各パラメータについて説明します。
表9-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
など)の実行時に問題が発生した場合。
プロシージャDBMS_XMLSCHEMA.inPlaceEvolve
へのdiffXML
パラメータの値は、インプレースの拡張においてXML Schemaに適用される変更を指定したXML文書(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に準拠するドキュメント内の操作例を示します。
関連項目:
|
この項では、プロシージャの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>
とともに使用し、既存のノードを変更できます。
例9-6は、次の変更を指定するdiffXML
パラメータのXML文書を示しています。
複合型PartType
の削除。
最大長28での複合型PartType
の追加。
ShippingInstructions
要素の前へのコメントの追加。
必須要素shipmethod
のShippingInstructions
要素への追加。
例9-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>