|Oracle® XML DB Developer's Guide
10g Release 1 (10.1)
Part Number B10790-01
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:
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
() involves copying existing instance documents to temporary tables, dropping and re-registering the XML schema, and copying the instance documents to the new
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()".
The following are the limitations of
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
X is dependent on this 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.
Here are some guidelines for using
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.
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.
CopyEvolve(), specifying the XML schema URLs, new schemas, and transformations.
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 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.
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.
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%';
Schema evolution may involve dropping/creating types. Hence you need type-related privileges such as
CREATE TYPE, and
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.
Here is the
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
|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. 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;
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.
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:
It creates default tables while registering the new schemas.
It creates nondefault tables by a statement of the following form:
CREATE TABLE <TABLE_NAME> OF XMLType OID '<OID>' XMLSCHEMA <SCHEMA_URL> ELEMENT <ELEMENT_NAME>
where <OID> is the original OID of the table, before it was dropped.
XMLType columns are added using a statement of the following form:
ALTER TABLE <Table_Name> ADD (<Column_Name> XMLType) XMLType column <Column_Name> xmlschema <Schema_Url> ELEMENT <Element_Name>
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
|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.|
XMLType columns the temp table will have the following columns:
Table 7-4 XML Schema Evolution: XMLType Column Temporary Table Columns
|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.|
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