Skip Headers

Oracle® XML DB Developer's Guide
10g Release 1 (10.1)

Part Number B10790-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Feedback

Go to previous page
Previous
Go to next page
Next
View PDF

7 XML Schema Evolution

This chapter describes how you can update your XML schema after you have registered it with Oracle XML DB. XML schema evolution is the process of updating your registered XML schema.

This chapter contains these topics:

Introducing XML Schema Evolution

Oracle XML DB supports the W3C XML Schema recommendation. XML instances that conform to an XML schema can be stored and retrieved using SQL and protocols such as FTP, HTTP, and WebDAV. In addition to specifying the structure of XML documents, XML schemas determine the mapping between XML and object-relational storage.

In prior releases an XML schema, once registered with Oracle XML DB at a particular URL, could not be modified or evolved because there may be XMLType tables that depend on the XML schema. There was no standard procedure for schema evolution. This release supports XML schema evolution by providing a PL/SQL procedure CopyEvolve() a part of the DBMS_XMLSCHEMA package. CopyEvolve() involves copying existing instance documents to temporary tables, dropping and re-registering the XML schema, and copying the instance documents to the new XMLType tables.

With copyevolve() you can evolve your registered XML schema in such a way that existing XML instance documents continue to be valid. If you do not care about the existing documents, you can simply drop the XMLType tables dependent on the XML schema, delete the old XML schema, and register the new XML schema at the same URL.

CopyEvolve() has certain limitations. These are described in the section, "Limitations of CopyEvolve()".

Limitations of CopyEvolve()

The following are the limitations of CopyEvolve():

  • Indexes, triggers, constraints, RLS policies and other metadata related to the XMLType tables that are dependent on the schemas that are evolved, will not be preserved. These must be re-created after evolution.

  • If top-level element names are being changed, there are more steps to be followed after CopyEvolve() completes executing. See the section on "Top-Level Element Name Changes" for more details.

  • Data copy-based evolution cannot be used if there is a table with an object-type column that has an XMLType attribute that is dependent on any of the schemas to be evolved. For example, consider a table TAB1 that is created in the following way:

    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";

    The example assumes that an XML schema with a top-level element Employee has been registered under URL s1.xsd. It is not possible to evolve this XML schema since table TAB1 with column O with XMLType attribute X is dependent on this XML schema.

Example XML Schema

The following is an example of an XML schema along with typical changes you may want to make. Changes to be made are shown in bold. For changes to attributes, the old value is shown in italics, followed by the new value:

Example 7-1 Example XML Schema to be Evolved

This example shows the changes that need to be made in bold.

<schema targetNamespace="http://www.oracle.com/po.xsd"
         xmlns="http://www.w3.org/2001/XMLSchema"
         xmlns:po="http://www.oracle.com/po.xsd"
  elementFormDefault="qualified">
  <annotation>
   <documentation xml:lang="en">
     Purchase Order schema for US PO's.
   </documentation>
  </annotation>
<complexType name="Address">
 <sequence>
  <element name="name" type="string"/>
  <element name="street" type="string"/>
  <element name="city" type="string"/>
 </sequence>
</complexType>
<!-- A type representing US States -->
 <simpleType name="USState">
  <restriction base="string">
   <enumeration value="NY"/>
   <enumeration value="TX"/>
   <enumeration value="CA"/>
   <enumeration value="FL"/>
  </restriction>
 </simpleType>
<complexType name="USAddress">
 <complexContent>
 <extension base="po:Address">
   <sequence>
     <element name="STATE" name="State" type="po:USState"/>
     <element name="zip" type="positiveInteger"/>
   </sequence>
 </extension>
 </complexContent>
</complexType>
<element name="PurchaseOrder">
   <complexType>
     <sequence>
        <element name="PO-Number" type="string"/>
        <element name="LineItems" maxOccurs="unbounded">
            <complexType>
              <sequence>
                <element name="part-num" type="string" maxLength="20"/>
                <element name="unit-price" type="float"/>
                <element name="quantity" type="integer"/>
             </sequence>
            </complexType>
           </element>
        <element name="shipTo" type="po:Address"/>
     </sequence>
   </complexType>

The next section describes steps for accomplishing copy-based schema evolution.

Guidelines for Using DBMS_XMLSCHEMA.CopyEvolve()

Here are some guidelines for using DBMS_XMLSCHEMA.CopyEvolve():

  1. First identify the XML schemas that are dependent on the XML schema to be evolved. You can acquire the URLs of the dependent XML schemas using the following query:

    SELECT dxs.schema_url
        FROM dba_dependencies dd, dba_xml_schemas dxs
        WHERE dd.referenced_name=(SELECT int_objname
              FROM dba_xml_schemas WHERE schema_url=<EVOL_SCH_URL>
              AND owner=<EVOL_SCH_OWNER>)
              AND dxs.owner = <EVOL_SCH_OWNER>
              AND dxs.int_objname=dd.name;

    In many cases, no changes may be necessary in the dependent XML schemas. But if the dependent XML schemas need to be changed, you must also prepare new versions of those XML schemas.

  2. If the existing instance documents do not conform to the new XML schema, you must provide an XSL style sheet that, when applied to an instance document, will transform it to conform to the new schema. This needs to be done for each XML schema identified in Step 1. The transformation must handle documents that conform to all top-level elements in the new XML schema.

  3. Call CopyEvolve(), specifying the XML schema URLs, new schemas, and transformations.

Top-Level Element Name Changes

The CopyEvolve() procedure assumes that top-level elements have not been dropped and that their names have not been changed in the new XML schemas. If there are such changes in your new XML schemas, you can call CopyEvolve() with the generateTables parameter set to FALSE and the preserveOldDocs parameter set to TRUE. In this way new tables are generated and the temporary tables holding the old documents are not dropped at the end of the procedure. You can then store the old documents in whatever form is appropriate and drop the temporary tables. See "DBMS_XMLSCHEMA.CopyEvolve() Syntax" for more details on the using these parameters.

Ensure that the XML Schema and Dependents are Not Used by Concurrent Sessions

Ensure that the XML schema and its dependents are not used by any concurrent session during the XML schema evolution process. If other concurrent sessions have shared locks on this schema at the beginning of the evolution process, DBMS_XMLSCHEMA.CopyEvolve() waits for these sessions to release the locks so that it can acquire an exclusive lock. However this lock is released immediately to allow the rest of the process to continue.

What Happens When CopyEvolve() Raises an Error? Rollback

CopyEvolve() either completely succeeds or raises an error in which case it attempts to rollback as much of the operation as possible. Evolving a schema involves many database DDL statements. When an error occurs, compensating DDL statements are executed to undo the effect of all steps executed to that point. If the old tables/schemas have been dropped they are re-created but any table/column/storage properties and auxiliary structures associated with the tables/columns like indexes, triggers, constraints, and RLS policies are lost.

Failed Rollback From Insufficient Privileges

In certain cases you cannot rollback the operation. For example, if table creation fails due to reasons not related to the new schema, such as, from insufficient privileges, there is no way to rollback. The temporary tables are not deleted even if preserveOldDocs is false, so that the data can be recovered. If the mapTabName parameter is null, the mapping table name is XDB$MAPTAB followed by a sequence number. The exact table name can be found using a query such as:

SELECT table_name FROM user_tables 
   WHERE table_name LIKE 'XDB$MAPTAB%';

Using CopyEvolve(): Privileges Needed

Schema evolution may involve dropping/creating types. Hence you need type-related privileges such as DROP TYPE, CREATE TYPE, and ALTER TYPE.

You need privileges to delete and register the XML schemas involved in the evolution. You need all privileges on XMLType tables that conform to the schemas being evolved. For XMLType columns the ALTER TABLE privilege is needed on corresponding tables. If there are schema-based XMLType tables or columns in other users' database schemas, you need privileges such as CREATE ANY TABLE, CREATE ANY INDEX, SELECT ANY TABLE, UPDATE ANY TABLE, INSERT ANY TABLE, DELETE ANY TABLE, DROP ANY TABLE, ALTER ANY TABLE, and DROP ANY INDEX.

To avoid having to grant all these privileges to the schema owner, Oracle Corporation recommends that the evolution be performed by a DBA if there are XML schema-based XMLType table or columns in other users' database schemas.

DBMS_XMLSCHEMA.CopyEvolve() Syntax

Here is the DBMS_XMLSCHEMA.CopyEvolve() syntax:

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);

Table 7-1 DBMS_XMLSCHEMA.CopyEvolve(): Parameters

Parameter Description
schemaURLs Varray of URLs of XML schemas to be evolved. This should include the dependent schemas as well. Unless the force parameter is TRUE, the URLs should be in the dependency order, that is, if URL A comes before URL B in the Varray, then schema A should not be dependent on schema B but schema B may be dependent on schema A.
newSchemas Varray of new XML schema documents. Specify this in exactly the same order as the corresponding URLs. If no change is necessary in an XML schema, provide the unchanged schema.
transforms Varray of XSL documents that will be applied to XML schema based documents to make them conform to the new schemas. Specify these in exactly the same order as the corresponding URLs. If no transformations are required, this parameter need not be specified.
preserveOldDocs If this is TRUE the temporary tables holding old data are not dropped at the end of schema evolution. See also "How DBMS_XMLSCHEMA.CopyEvolve() Works".
mapTabName Specifies the name of table that maps old XMLType table or column names to names of corresponding temporary tables.
generateTables By default this parameter is TRUE; if this is FALSE, XMLType tables or columns will not be generated after registering new schemas. If this is FALSE, preserveOldDocs must be TRUE and mapTabName must be non-null.
force If this is TRUE errors during the registration of new schemas are ignored. If there are circular dependencies among the schemas, set this flag to TRUE to ensure that each schema is stored even though there may be errors in registration.
schemaOwners Varray of names of schema owners. Specify these in exactly the same order as the corresponding URLs.

Table 7-2 DBMS_XMLSCHEMA.CopyEvolve(): Errors and Exceptions

Error Number and Message Cause Action
30942 XML Schema Evolution error for schema '<schema_url' table "<owner_name>.<table_name>" column '<column_name>' The given XMLType table or column that conforms to the given schema had errors during evolution. In the case of a table the column name will be empty. See also the more specific error that follows this. Based on the schema, table, and column information in this error and the more specific error that follows, take corrective action.
30943 XML Schema '<schema_url' is dependent on XML schema '<schema_url>' Not all dependent XML schemas were specified or the schemas were not specified in dependency order, that is, if schema S1 is dependent on schema S, S must appear before S1. Include the previously unspecified schema in the list of schemas or correct the order in which the schemas are specified. Then retry the operation.
30944 Error during rollback for XML schema '<schema_url' table "<owner_name>.<table_name>" column '<column_name>' The given XMLType table or column that conforms to the given schema had errors during a rollback of XML schema evolution. For a table the column name will be empty. See also the more specific error that follows this. Based on the schema, table, and column information in this error and the more specific error that follows, take corrective action.
30945 Could not create mapping table '<table_name' A mapping table could not be created during XML schema evolution. See also the more specific error that follows this. Ensure that a table with the given name does not exist and retry the operation.
30946 XML Schema Evolution warning: temporary tables not cleaned up An error occurred after the schema was evolved while cleaning up temporary tables. The schema evolution was successful. If you need to remove the temporary tables, use the mapping table to get the temporary table names and drop them.

Example 7-2 Using DBMS_XMLSCHEMA.CopyEvolve() to Update an XML Schema

In this example, the address.xsd schema needs to be evolved. The new XML schema adds a new element State as a child of the top-level Address element. It also renames the element STREET to Street. Since it renames an existing element, the old instance documents may not conform to the new schema and so an XSL transformation is required to transform them to conform to the new schema.

declare
  newaddr    XMLType;
  transform  XMLType;
begin
  newaddr := xmltype(
   '<schema targetNamespace="http://www.example.com/IPO"
          xmlns="http://www.w3.org/2001/XMLSchema"
          xmlns:ipo="http://www.example.com/IPO"
          xmlns:xdb="http://xmlns.oracle.com/xdb"
          elementFormDefault="qualified">
  
  <element name="Address" xdb:defaultTable="ADDR_TAB">
    <complexType>
      <sequence>
        <element name="Name"   type="string"/>
        <element name="Street" type="string"/>
        <element name="City"   type="string" />
        <element name="State"   type="string" />
      </sequence>
    </complexType>
  </element>
  </schema>');
 
transform := xmltype(
  '<xsl:stylesheet  version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.example.com/IPO"
 xmlns:ipo="http://www.example.com/IPO">
   <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/ipo:Address/ipo:STREET">
    <Street>
      <xsl:for-each select="@*|node()">
         <xsl:copy-of select="."/>
      </xsl:for-each>
    </Street>
  </xsl:template>
 </xsl:stylesheet>');
 
dbms_xmlschema.CopyEvolve(xdb$string_list_t('address.xsd'), 
      XMLSequenceType(newaddr), XMLSequenceType(transform));
end;

How DBMS_XMLSCHEMA.CopyEvolve() Works

The DBMS_XMLSCHEMA.CopyEvolve() procedure is used to evolve registered XML schemas such that existing XML instances continue to remain valid.


Note:

Since this procedure deletes all documents conforming to the XML schemas during the process of schema evolution, backup all these documents and schemas before executing this procedure.

First CopyEvolve() copies the data in schema based XMLType tables and columns to temporary tables. It then drops the tables and columns and deletes the old XML schemas. After registering the new XML schemas, it creates XMLType tables and columns and populates them with data (unless the genTables parameter is FALSE) but it does not create any auxiliary structures such as indexes, constraints, triggers, and row-level security (RLS) policies. CopyEvolve() creates the tables and columns in the following way:

When a new schema is registered, types or beans are generated if the registration of the corresponding old schema had generated types or beans. If an XML schema was global before the evolution it will be global after the evolution. Similarly if an XML schema was local before the evolution it will be local (owned by the same user) after the evolution.You have the option to preserve the temporary tables that contain the old documents by passing in TRUE for the preserveOldDocs parameter. In this case, the procedure does not drop the temporary tables at the end. All temporary tables are created in the current user's database schema. For XMLType tables the temp table will have the following columns:

Table 7-3 XML Schema Evolution: XMLType Table Temporary Table Columns

Name Type Comment
Data CLOB XML doc from old table in CLOB format.
OID RAW(16) OID of corresponding row in old table.
ACLOID RAW(16) This column is present only if old table is hierarchy enabled. ACLOID of corresponding row in old table.
OWNERID RAW(16) This column is present only if old table is hierarchy enabled. OWNERID of corresponding row in old table.

For XMLType columns the temp table will have the following columns:

Table 7-4 XML Schema Evolution: XMLType Column Temporary Table Columns

Name Type Comment
Data CLOB XML document from old column in CLOB format.
RID ROWID ROWID of corresponding row in the table that this column was a part of.

The CopyEvolve() procedure stores information about the mapping from the old table or column name to the corresponding temporary table name in a separate table specified by the mapTabName parameter. If preserveOldDocs is TRUE, the mapTabName parameter must be non-null and must not be the name of any existing table in the current user's schema. Each row in the mapping table has information about one of the old tables/columns. Table 7-5 shows the mapping table columns.

Table 7-5 CopyEvolve() Mapping Table

Column Name Column Type Comment
SCHEMA_URL VARCHAR2(700) URL of schema to which this table/column conforms.
SCHEMA_OWNER VARCHAR(30) Owner of the schema.
ELEMENT_NAME VARCHAR2(256) Element to which this table/column conforms.
TABLE_NAME VARCHAR2(65) Qualified Name of table (<owner_name>.<table_name>).
TABLE_OID RAW(16) OID of table.
COLUMN_NAME VARCHAR2(4000) Name of column (this will be null for XMLType tables).
TEMP_TABNAME VARCHAR2(30) Name of temporary table which holds the data for this table/column.

You can also avoid generating any tables or columns after registering the new XML schema, by using FALSE as the genTables parameter. If genTables is FALSE, the preserveOldDocs parameter must be TRUE and the mapTabName parameter must be non-null. This ensures that the data in the old tables is not lost. This is useful if you do not want the tables to be created by the procedure, as described in section "DBMS_XMLSCHEMA.CopyEvolve() Syntax".

By default it is assumed that all XML schemas are owned by the current user. If this is not true, you must specify the owner of each XML schema in the schemaOwners parameter.