この章では、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プロシージャがそれぞれ用意されています。この章では、各プロシージャの使用方法について説明し、それに関連するスキーマの拡張方法のガイドラインを提示します。
PL/SQLパッケージDBMS_XMLSCHEMA
のプロシージャcopyEvolve
を使用して、コピーに基づくXML Schemaの拡張を実行します。プロシージャcopyEvolve
は、既存のXMLインスタンス・ドキュメントをバックアップのために一時XMLType
表にコピーし、古いバージョンのXML Schemaを削除し(関連インスタンス・ドキュメントも削除します)、新しいバージョンを登録して、バックアップしたインスタンス・ドキュメントを新規XMLType
表にコピーします。問題が発生した場合、バックアップ・コピーはリストアされます。「プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック」を参照してください。
プロシージャcopyEvolve
を使用すると、既存のXMLインスタンス・ドキュメントの有効性を保持しながら、登録されたXML Schemaを拡張できます。
例10-1は、例3-10の発注書XML Schemaの修正バージョンのリストの一部を示します。完全な修正スキーマのリストは、例A-2を参照してください。この例では、太字のテキストが新規部分、または元のスキーマと異なる部分です。
例10-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);
表10-1に、各パラメータについて説明します。表10-2に、このプロシージャに関連するエラーについて説明します。
表10-1 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEのパラメータ
パラメータ | 説明 |
---|---|
|
拡張するXML SchemaのURLのVARRAY( |
|
新しいXML Schema文書( |
|
XML Schemaに基づく文書を新しいスキーマに準拠させるために、その文書に適用されるXSL文書( |
|
このパラメータが |
|
古い |
|
このパラメータのデフォルトは |
|
このパラメータが |
|
スキーマ所有者名のVARRAY。対応するURLと同じ順序で正確に指定します。 |
|
データのコピーの段階で、 |
|
その他のオプション。オプションは、 |
表10-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の警告: 一時表がクリーンアップされていません |
スキーマが拡張された後、一時表のクリーンアップでエラーが発生しました。スキーマの拡張は正常に終了しています。 |
一時表を削除する必要がある場合は、マッピング表を使用して一時表の名前を取得し、その一時表を削除します。 |
プロシージャ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
オブジェクト属性を処理しないことに注意してください。そのような場合はエラーが発生します。
次は、プロシージャ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
表または列がある場合は、これらのすべての権限をデータベース・スキーマ所有者に付与しなくてすむように、データベース管理者が拡張を実行することをお薦めします。
登録済のXML Schemaを変更した後は、そのXML Schemaを使用していた既存のXMLインスタンス・ドキュメントも更新する必要があります。更新するには、各インスタンス・ドキュメントにXSLTスタイルシートを適用します。このスタイルシートは、古いXML Schemaと新しいXML Schemaの差分を表します。
例10-2はファイルevolvePurchaseOrder.xsl
内のスタイルシートです。これによって、古いXML Schemaを使用していた既存の発注書が新しいXML Schemaを使用するように変換されます。
例10-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>
例10-3では、修正されたXML Schemaおよび拡張XSLスタイルシートをOracle XML DBリポジトリにロードします。
例10-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;/
例10-4は、プロシージャDBMS_XMLSCHEMA.copyEvolve
を使用し、XSLスタイルシートevolvePurchaseOrder.xsl
によってXML Schema purchaseOrder.xsd
をrevisedPurchaseOrder.xsd
に拡張する方法を示しています。
例10-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>
プロシージャ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
表には、表10-3で示すような列が一時表に存在します。
表10-3 XML Schemaの拡張: XMLType表の一時表の列
名前 | 型 | コメント |
---|---|---|
|
|
|
|
|
古い表で対応する行の |
|
|
この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行の |
|
|
この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行の |
XMLType
列には、表10-4で示すような列が一時表に存在します。
表10-4 XML Schemaの拡張: XMLType列の一時表の列
名前 | 型 | コメント |
---|---|---|
|
|
|
|
|
この列が含まれる表の対応する行の |
プロシージャCopyEvolve
は、古い表または列名から、mapTabName
パラメータで指定された個別の表に対応する一時表名へのマッピングに関する情報を格納します。preserveOldDocs
がTRUE
の場合、mapTabName
パラメータは、NULL
以外の値であり、かつ現行ユーザーのスキーマに存在しない表名である必要があります。マッピング表の各行には、古い表または列の1つに関する情報が含まれます。表10-5に、マッピング表の列を示します。
表10-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拡張でサポートされる操作」を参照してください。
インプレース拡張を使用する際の主要な制限は一般に、指定されたXML Schemaが、下位互換にのみインプレース拡張できることという要件として記述できます。つまり、下位互換とは、指定のXML Schemaに対して検証される可能性のあるすべてのインスタンス・ドキュメントは、そのXML Schemaの将来の(拡張)バージョンでも同様に検証される必要があります。
これは既存のインスタンス・ドキュメントに限らず、すべての可能な準拠インスタンス・ドキュメントに適用されます。バイナリXMLとして格納されたXMLデータの場合、下位互換性は、バイナリXML処理に影響を与えるXML Schema注釈は拡張中に変更できないことも意味します。下位互換性については項「下位互換性の制約」で説明します。
この一般的な下位互換性制限に加え、インプレースの拡張には他の制約もあります。それについては項「インプレース拡張のその他の制限」で説明します。
この項で説明する制約は、拡張されたXML Schemaの下位互換性を保証するため、以前のXML Schemaを満足させる可能なインスタンス・ドキュメントはすべて、新しいスキーマを満足させます。
XML Schemaへの一定の変更は、関連付けられるディスク上のインスタンス・ドキュメントのレイアウトが変更されるため許可されていません。これはオブジェクト・リレーショナル記憶域の場合と同様、記憶域のレイヤーがXML Schemaから導出された情報と密に統合されている場合に一般的な状況です。
そのような例の1つは、オブジェクト・リレーショナル記憶域のマッピングとして登録されたXML Schemaで、1つの複合型を2つの複合型に分割することで拡張されます。例10-5では、複合型ShippingInstructionsType
が2つの複合型Person-Name
とContact-Info
に分割され、ShippingInstructionsType
複合型は削除されます。
例10-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に関連付けられているインスタンス・ドキュメントがないため、データのコピーが不要な場合でも、今後のインスタンス・ドキュメントに対応するために既存の表のレイアウトを変更する必要があります。
インスタンス・ドキュメントのDOMの再現性に影響を及ぼすような方法では、スキーマ要素の再順序付けにインプレースの拡張を使用できません。たとえば、複合型定義での<sequence>
要素内の要素の順序は変更できません。具体的には、複合型ShippingInstructionsType
でその子要素をname
、address
、telephone
の順にする必要がある場合、順序をname
、telephone
、address
に変更するためにインプレースの拡張は使用できません。
この項では、インプレース・スキーマ拡張でサポートされる操作について説明します。サポートされる操作のこのリストは、必ずしも完全ではありません。ここにリストされている操作のうち、指定した、特定のコンテキストでは許可されないものもあります。特に、ここで説明する一部の操作は、バイナリ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);
表10-6に、各パラメータについて説明します。
表10-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に適用される変更を指定した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>
とともに使用し、既存のノードを変更できます。
例10-6は、次の変更を指定するdiffXML
パラメータのXML文書を示しています。
複合型PartType
の削除。
最大長28での複合型PartType
の追加。
ShippingInstructions
要素の前へのコメントの追加。
必須要素shipmethod
のShippingInstructions
要素への追加。
例10-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>