Хранение XML данных (Storing XML Data)

Марк Скандина, Бен Чанг, Джайню Ванг

Глава 9 из книги "Oracle Database 10g XML & SQL: Design, Build, & Manage XML Applications in Java, C, C++, & PL/SQL" by Mark ScardinaBen Chang Jinyu Wang , изд. Osborne, ISBN: 0072229527, 2004, 600 стр.

Оригинальный текст главы 9 выложен в открытом доступе по адресу http://www.oracle.com/technology/books/pdfs/ch9_oracle10g_xml.pdf

Перевод: Oracle Magazine RE

Часть 1

В Oracle Database 10g у вас есть несколько возможностей хранения XML данных. Вы можете разделить XML документ на части и хранить данные в одной или нескольких реляционных таблицах, помещать XMLType-ы целиком в CLOB-ы или зарегистрировать XML схему и хранить их в объектно-ориентированой памяти на языке XML Schema, предназначеном для XMLType. Если нет необходимости корректировки XML-контента, также можно сохранить XML документы как внешние, используя механизм External Tables (внешних таблиц).

Эта глава дает содержит обзор способов хранения XML, доступных в Oracle Database 10g и демонстрирует различные варианты применения этих технологий. Даются примеры использования утилит Oracle SQL*Loader и XML SQL Utility (XSU) для загрузки XML документов в или XMLType-таблицу, или реляционную таблицу в Oracle Database 10g. Мы начнем с простейшего формата сохранения: CLOB XMLTypes (XMLType в CLOB).

Хранение XML документов в CLOB XMLTypes

Используя CLOB XMLType, XML документы хранятся как CLOB'ы c установкой XML интерфейсов, предоставляемых XMLType. Не смотря на то, что перед загрузкой данных можно опционально запустить любой XML процесс, например, ввод данных XML в XML схему или DTD, размещение CLOB XMLType не нуждается ни в каком XML процессе, за исключением проверки формальной правильности и разрешения существования.

Запрос и обновление CLOB XMLType

Хранение в виде CLOB XMLType наилучшим образом консервирует оригинальный формат XML документов и дает максимальную гибкость при развитии XML схемы.

Однако, хранение XML документов в CLOB XMLTypes приводит к дорогой избыточной обработке при запросе XML контента такими функциями, как XMLType.Extract() или XMLType.ExistsNode(), поскольку эти операции требуют во время обработки построения в оперативной памяти дерева XML DOM и выполнения функциональных Xpath оценок. Кроме того, любая операция обновления (update) может быть осуществлена только на уровне документа. Это означает, что вам необходимо обновлять весь XML документ после каждого даже незначительного изменения какого-либо XML элемента.

Поэтому, как правило, следует избегать использования XMLType функций при выполнении незначительных XML обновлений или запросов с задействованием Xpath при действиях с CLOB XMLTypes.

Вместо XPath-запросов к CLOB XMLTypes, Oracle Text обеспечивает поиск по всему тексту, поддерживая ограниченное множество [путей] XPaths. Эта функциональность позволяет выполнять ХРath запросы в XMLTypes, используя CONTEXT индекс, создаваемый Oracle Text, который является очень полезным и масштабируемым механизмом для приложений, что мы обсудим в главе 11 (“Searching XML Data”).

Действия с символьными кодировками в CLOB XMLTypes

Нужно знать, что когда XML документ хранится в Oracle Database, символьная перекодировка автоматически выполняется перед вводом данных, при этом по набору символов (character set – кодовая таблица), установленному в базе данных, конвертируются все текстовые данные, включая XML документы. Исключением является хранение типов данных BLOB, NCHAR и NCLOB.

Вследствие такого неявного преобразования набора символов, актуальная кодировка XML данных и декларируемая в прологе <?XML?> кодировка - не одно и то же. В нынешнем релизе Oracle Database 10g, XMLType API игнорирует декларируемую в прологе <?XML?> кодировку и предполагает, что XML данные хранятся в CLOB XMLTypes в кодировке базы данных. Следовательно, при загрузке клиентских XML данных необходимо убедиться, что конверсия кодов успешно выполнена.

Если XML документ изначально хранится в кодировке клиента, отличной от алфавита базы данных, то для того, чтобы гарантировать правильность конверсии из кодировки клиента в алфавит базы данных, необходимо установить переменную среды NLS_LANG, называющую кодовую таблицу клиента. Однако, если в переменной установлена такая же кодировка, как и набор символов базы данных, оригинальный текст в базе данных будет сохранен “как есть” без проверки правильности символов и конверсии. Другими словами, если переменная среды NLS_LANG не установлена или установлена неправильно, а XML документ имеет другую кодировку, чем база данных, в базе данных будет хранится просто мусор.

ЗАМЕЧАНИЕ

Если XML документ содержит символы, которые не включены в алфавит базы данных, то перед добавлением данных в CLOB XMLTypes вы получите ошибку Invalid Character. Возможным решением может служить использование NCLOB или BLOB для сохранения данных в базе данных и построение XML приложения среднего слоя или внешней PL/SQL процедуры, использющих XDK API для обработки XML данных.

Из-за конверсии алфавита может произойти конфликт между действующей кодировкой и кодировкой, декларируемой в прологе <?XML?>, при считывании XML данных из CLOB XMLTypes, во избежание чего следует создать реверсивную кодовую таблицу (reverse character set) или заменить декларирацию в <?XML?> прологе, чтобы сделать согласовать кодировки. Это важно, так как синтаксический анализатор XML использует первые 4 байта пролога <?XML?> для определения кодировки XML документов, и может быть определено только, что алфавит базируется на ASCII- или на EBCDIC- кодировках. Если он базируется на ASCII кодировке, то синтаксический анализатор XML может определить только, что он является UTF-8 или UTF-16. Иначе, это зависит от атрибутов кодирования в <?XML?>. Поэтому, если вы имеете XML документ не в UTF-8 или UTF-16 кодировках, то вы должны вставить правильную XML декларированную кодировку, чей алфавит используется, как показано ниже:

<?xml version="1.0" encoding='Shift-JIS'?>

Хранение XML документов в XMLTypes на языке XML Schema

Для увеличения скорости ХРath запросов и незначительных обновлений XMLTypes, можно создать XMLTypes на осенове XML Schema. Один из способов это сделать – надо сопоставить зарегистрированные XML схемы с столбцами или таблицами XMLType, используя XMLSCHEMA. Вы также можете создать XMLType таблицы, специфицируя аннотацию DEFAULT TABLE в зарегистрированных XML схемах.

Все эти подходы создают XMLTypes, базированные на XML Schema, где наборы объектно-реляционных таблиц/объектов соответствуют XML объектам, определенным в XML схеме. Единственное различие между созданием заданной по умолчанию(default) в процессе регистрации XML схемы таблицы и использованием ключевого слова (keyword) XMLSCHEMS состоит в том, что первое решение позволяет XML документам, соответствующим зарегистрированной XML схеме, находиться под управлением репозитория Oracle XML DB. Если имеет место поддержка репозитория XML DB, можно не только извлекать и обновлять XML в SQL, но также и управлять XML документами, хранящимися в репозитории XML DB, используя такие интерфейсные протоколы, как FTP и HTTP/WebDAV.

Регистрация XML схемы

Регистрация XML схемы определяется отображением XML-to-SQL и иерархической объектно-реляционной структурой для сохранения XML документов в базе данных Oracle. Мы посмотрим, как это жделается, используя созданных в 8-й главе пользователя по имени DEMO и папку WebDAV.

Первое, вам нужно скопировать XML схему для записей о клиентах, contact_simple.xsd, в папку /public WebDAV. Далее содержание этой схемы:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Customer" type="CustomerType"/>
<xsd:complexType name="CustomerType">
<xsd:sequence>
<xsd:element name="NAME" type="xsd:string"/>
<xsd:element name="EMAIL" type="xsd:string"/>
<xsd:element name="ADDRESS" type="xsd:string"/>
<xsd:element name="PHONE" type="phoneType"/>
<xsd:element name="DESCRIPTION" type="contentType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ContentType" mixed="true">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded"
processContents="skip"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="phoneType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\(\d{3}\)\d{3}-\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

Для регистрации этой XML схемы в XML DB можно применить следующую PL/SQL процедуру:

ALTER SESSION SET EVENTS='31098 trace name context forever';
BEGIN
DBMS_XMLSCHEMA.registerURI(
'http://localhost:8080/public/contact_simple.xsd',
'/public/contact_simple.xsd',
LOCAL=>TRUE, GENTYPES=>TRUE, GENBEAN=>FALSE,
GENTABLES=>TRUE);
END;
ЗАМЕЧАНИЕ

Для использования команды ALTER SESSION вам нужно зарегистрироваться как SYS и предоставлять привилегии ALTER SESSION пользователю DEMO, используя команду “GRANT ALTER SESSION TO DEMO”. Иначе вы получите сообщение об ошибке ORA-01031: Insufficient Privileges (Недостаточнопривилегий).

В функции DBMS_XMLSCHEMA.registerURI() первый параметр - это схема URI, http://localhost:8080/public/contact_simple.xsd, которая уникально идентифицирует зарегистрированную XML схему в XML DB. Второй параметр - это XML DB URI (XDBUri), /public/contact_simple.xsd, обращающиеся к файлу contact_simple.xsd в папке /public репозитория XML DB. Следующие параметры определяют регистрируемую схему: локальная - (LOCAL=>TRUE) или глобальная (LOCAL=>GLOBAL), а также что будет создано: объектные типы - (GENTYPES=>TRUE) и таблицы по умолчанию (default) (GENTABLES=>TRUE). Параметр GENBEAN не обязателен и в данное время не выполняет никакой функции. Если XML схема зарегистрирована как глобальная в XML DB, то она может быть совместно используемой различными пользователями базы данных. Иначе совместное использование XML схемы не разрешается. Можно установить GENTABLES=>FALSE, если не надо, чтобы перед регистрацией XML схемы Oracle XML DB создавал default таблицы. В таком случае можно создать XMLType таблицы, используя ключевое слово XMLSCHEMA, как показано ниже:

CREATE TABLE customer_xmltype_tbl OF XMLTYPE
XMLSCHEMA "http://localhost:8080/public/contact_simple.xsd"
ELEMENT "Customer";

Кроме того, можно использовать следующий синтаксис для определения столбцов XMLType, хранящихся при использовани XML Schema:

CREATE TABLE customer_col_tbl(
id NUMBER,
record XMLType)
XMLTYPE COLUMN record STORE AS OBJECT RELATIONAL
XMLSCHEMA "http://localhost:8080/public/contact_simple.xsd"
ELEMENT "Customer";

Коль скоро для хранения XMLType столбцов и таблиц применяются одни и те же приемы, в последующих секциях мы будем детально рассматривать только XMLType таблицы на XML Schema.

В процессе регистрации XML схемы можно использовать следующую команду для создания трассировочного файла в [директории, определяемой параметром инициализации USER_DUMP_DIR], в котором отразятся DLL, используемые для создания объектных таблиц и типов данных:

ALTER SESSION SET EVENTS='31098' TRACE NAME CONTEXT FOREVER;

Для размещения трассировочного файла необходимо проверить ID идентификатор текущей сессии, обратившись к представлениям V$SESSION и V$PROCESS. Перед запросом к V$SESSION и V$PROCESS от имени пользователя DEMO, вам необходимо войти как SYS и дать пользователю DEMO привилегию SELECT из представлений V$SESSION и V$PROCESS, как показано далее:

GRANT SELECT ON V_$SESSION TO DEMO;
GRANT SELECT ON V_$PROCESS TO DEMO;
ЗАМЕЧАНИЕ

Коль скоро V$SESSION и V$PROCESS - это просто синонимы представлений, то никаких других привилегий на них дать нельзя.

Применив следующую SQL команду можно найти идентификатор сессии, которая соответствует трассировочному файлу:

SELECT a.spid
FROM V$PROCESS a, V$SESSION b
WHERE a.addr=b.paddr
AND b.audsid=userenv('sessionid');

Возвращаемое значение:

SPID
------------
2796

У трассировочного файла есть имя, структурированное как orclX_ora_<Session_id>.trc и можно узнать [значение параметра] USER_DUPM_DIR, выполнив следующую команду от лица SYS:

SQL> SHOW PARAMETERS user_dump_dest
NAME TYPE VALUE
-----------------------------------------------------------
user_dump_dest string D:\ORACLE\ADMIN\ORCLX\UDUMP

И далее, наличие трассировочного файла orclX_ora_<Session_id>.trc в USER_DUPM_DIR можно проверить следующей командой:

SQL> host ls d:\oracle\admin\orclX\udump\orclX_ora_2796.trc
orclX_ora_2796.trc
 
 

Так как этот файл содержит список DDL, используемых для создания объектных таблиц или типов данных, это нужная справка при отладке регистрации XML схемы.

Теперь давайте более подробно рассмотрим созданную структуру хранения, выполнив в SQL *Plus следующую команду:

SQL> SELECT object_name, object_type
2 FROM USER_OBJECTS
3 WHERE object_name LIKE '%Customer%';
OBJECT_NAME OBJECT_TYPE
------------------------- --------------------
Customer260_TAB TABLE
Customer260_TAB$xd TRIGGER
CustomerType259_T TYPE

Результат показывает, что в процессе регистрации XML схемы были созданы три объекта. Если более детально посмотреть на определения типов и таблиц, то можно увидить и другую информацию о созданных объектах. Во-первых, можно получить структуру таблицы Customer260_TAB:

SQL> DESC "Customer260_TAB";

В результате имеем следующее:

Name                                        Null?            Type
----------------------------------------- -------- -------------------
TABLE of SYS.XMLTYPE(XMLSchema "http://localhost:8080/public/contact_
simple.xsd" Element "
Customer") STORAGE Object-relational TYPE "CustomerType259_T"
ЗАМЕЧАНИЕ

Даже если XML элемент использует смешанный регистр или нижний регистр (mixed case or lowercase), по умолчанию имена default таблицы и объектов будут зависимы от регистра. Следовательно, необходимо использовать двойные кавычки при обращениях к таким именам, как “Customer260_TAB”.

Представленная выше структура показывает что:

  • Customer260_TAB -
  • это XMLType таблица
  • XMLType объекты в таблице ассоциированы с зарегистрированной XML схемой http://localhost:8080/public/contact_simple.xsd
  • Корневой элемент XML документа - <Customer>
  • Объектный тип, использованный для сохранения XMLType, - CustomerType259_T

Глядя на эту структуру CustomerType259_T, можно увидеть, что этот тип содержит

SQL> DESC "CustomerType259_T"
"CustomerType259_T" is NOT FINAL
         Name            Null?                Type
----------------------------------- -------- ------------------------
SYS_XDBPD$                                         XDB.XDB$RAW_LIST_T
NAME                                               VARCHAR2(4000 CHAR)
EMAIL                                              VARCHAR2(4000 CHAR)
ADDRESS                                            VARCHAR2(4000 CHAR)
PHONE                                              VARCHAR2(4000 CHAR)
DESCRIPTION                                        contentType257_T

Все XML элементы в XMLType корреспондированы с соответствующими типах данных базы данных. В этом примере элементы NAME, EMAIL, ADDRESS и PHONE, как простейшие типы в XML схеме, сохранены как VARCHAR2. Так как в XML схеме нет ограничения на длину строки, Oracle XML DB установил 4000 символов, как значение по умолчанию ширины данных столбцов. С другой стороны, новые объектные типы были созданы для сложных типов, определенных в XML схеме. В данном примере contentType257_T создан для хранения описания заказчиков, как показано далее:

SQL> DESC "contentType257_T";
"contentType257_T" is NOT FINAL
Name                              Null?     Type
---------------------------------- -------- ------------------------
SYS_XDBPD$                                         XDB.XDB$RAW_LIST_T
SYS_XDBANY258$                                     VARCHAR2(4000 CHAR)

Заметим, что Oracle XML DB определяет столбец SYS_XDBANY258$ как VARCHAR2 (4000) для хранения элемента <xsd:any/>, определенного в элементе <DESCRIPTION>. Столбец SYS_XDBPD$ - это позиция столбца дескриптора, созданного XML DB для сохранить DOM точность XML документов. Информация, такая как: комментарии, инструкции обработки, префиксы пространства имен и список родственных XML элементов, сохраняется в столбце SYS_XDBPD$. Следовательно, этот столбец используется, чтобы сохранить целостность оригинального XML документа в DOM трансверсалях (transversals).

Для еще более детального изучения таблицы Customer260_TAB следует запросить представление USER_TAB_COLS:

SQL> SELECT column_name,data_type,

2 CASE WHEN hidden_column='YES' THEN 'hidden'
3 WHEN virtual_column='YES' THEN 'virtual'
4 ELSE null END as attr
5 FROM USER_TAB_COLS
6 WHERE table_name='Customer260_TAB'
7 ORDER by virtual_column desc, column_name;
COLUMN_NAME          DATA_TYPE                 ATTR
-------------------- ------------------------- -------
SYS_NC_ROWINFO$      XMLTYPE                   virtual
XMLDATA              CustomerType259_T         hidden
ACLOID               RAW                       hidden
OWNERID              RAW                       hidden
SYS_NC00007$         RAW                       hidden
SYS_NC00014$         RAW                       hidden
SYS_NC_OID$          RAW                       hidden
SYS_NC00009$         VARCHAR2                  hidden
SYS_NC00010$         VARCHAR2                  hidden
SYS_NC00011$         VARCHAR2                  hidden
SYS_NC00012$         VARCHAR2                  hidden
SYS_NC00016$         VARCHAR2                  hidden
SYS_NC00008$         XDB$RAW_LIST_T            hidden
SYS_NC00015$         XDB$RAW_LIST_T            hidden
XMLEXTRA             XMLTYPEEXTRA              hidden
SYS_NC00004$         XMLTYPEPI                 hidden
SYS_NC00005$         XMLTYPEPI                 hidden
SYS_NC00013$         contentType257_T          hidden

Заметим, что выражение CASE выбирает результат из одной или более альтернатив. Оно использует опцию SELECTOR для специфицирования выражения, чье значение определяет, какую из альтернатив возвращать. Стандартное выражение CASE имеет следующую форму:

CASE selector
WHEN expression1 THEN result1
WHEN expression2 THEN result2
...
WHEN expressionN THEN resultN
[ELSE resultN+1]
END;

Из запроса можно видеть, что таблица Customer260_TAB содержит один виртуальный (virtual) столбец с именем SYS_NC_ROWINFO$, несколько скрытых (hidden) столбцов, включая XMLDATA, ACLOID, OWNERID, XMLEXTRA, и набор столбцов $SYS_NC<number>$.

Виртуальный столбец SYS_NC_ROWINFO$ - это объект XMLType, который идентифицирует строки XMLType таблицы. Например, в триггерах XMLType таблиц можно использовать :new.SYS_NC_ROWINFO$ для обращения к текущей строке данных.

Столбец XMLDATA ссылается на объекты SQL, используемые для сохранения XMLType. Это полезно, когда надо запросить или создать индексы в XMLType, полностью работая только с объектами SQL. В предшествующем примере XMLDATA - это псевдоним для объекта CustomerType259_T. Следовательно, можно добавить уникальное ограничение целостности (a unique constraint) на элемент EMAIL, ссылаясь на него, как XMLDATA.EMAIL, что показано далее:

ALTER TABLE Customer260_TAB ADD UNIQUE(XMLDATA.EMAIL);

XMLDATA.EMAIL ссылается на объекту, сохраняя контент элементов EMAIL в записях о клиентах. При наличии ограничения UNIQUE при попытке еще раз добавить такую же запись о клиенте, вы столкнетесь со следующей ошибкой:

ORA-00001: unique constraint (DEMO.SYS_C003626) violated

Некоторые из скрытых столбцов Customer260_TAB используются репозиторием Oracle XML DB. Например, в Oracle XML DB репозитории Access Control List (ACL) определяет разрешения для каждого ресурса. ACLOID специфицирует разрешения ACL для XMLType таблицы, а OWNERID специфицирует идентификатор владельца таблицы. Другие скрытые столбцы используются для построения иерархических отношений между XML элементами.

Исключение составляют XMLDATA и SYS_NC_ROWINFO$. Этими XMLType столбцами нельзя манипулировать или получить прямой доступ.

Аннотации XML схемы

Для управления соответствим между хранением XMLType и схемами XML нужно использовать аннотации Oracle XML DB. В Oracle Database 10g эти XML Schema аннотации представляют собой набор атрибутов, добавленных в XML схему, декларирующую имена объектов SQL, типы данных и разнообразные опции хранения. Все эти аннотации находятся в пространстве имен Oracle XML DB, http://xmlns.oracle.com/xdb, обычно использующим префикс xdb). Эти аннотации, главным образом, можно использовать, чтобы определить следующее:

  • DefaultTable -
  • Имя и атрибуты хранения XMLType таблицы по умолчанию (default), сохраняющей XML документы.
  • SQLNames -
  • SQL имена для XML элементов, определенных в XML схеме.
  • SQLTypes -
  • Имена типов SQL данных, используемых для хранения простых или составных типов данных, описанных в XML схеме. Для неограниченного XML элемента, обращающегося к набору SQL типов, xdb:SQLCollType используется для специфицирования имени типа.
  • MaintainDOM
  • - Атрибут, говорящий Oracle XML DB надо ли сохранять DOM точность элемента на выходе.
  • Storage Options
  • - Аннотации XML DB, такие, как: xdb:storeVarrayAsTable, xdb:mapUnboundedStringToLob, xdb:maintainOrder и xdb:SQLInline, специфицирующие возможности оптимального хранения.

Давайте рассмотрим следующую аннотированную XML схему для записей о клиентах customer_simple_ann.xsd, испытаем некую полезную технику разработки, а затем зарегистрируем ее в XML DB.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb" xdb:storeVarrayAsTable="true">
<xsd:element name="Customer" type="CustomerType"
xdb:defaultTable="CUSTOMER"/>
<xsd:complexType name="CustomerType" xdb:maintainDOM="false">
<xsd:sequence>
<xsd:element name="NAME" type="xsd:string"
xdb:SQLName="NAME" xdb:SQLType="VARCHAR2"/>
<xsd:element name="EMAIL" type="xsd:string"
xdb:SQLName="EMAIL" xdb:SQLType="VARCHAR2"/>
<xsd:element name="ADDRESS" type="xsd:string" maxOccurs="unbounded"
xdb:SQLName="ADDRESS" xdb:SQLCollType="ADDRESS_TYPE"
xdb:SQLType="VARCHAR2" xbd:maintainOrder="false"/>
<xsd:element name="PHONE" type="phoneType"
xdb:SQLName="PHONE"/>
<xsd:element name="DESCRIPTION" type="contentType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="contentType" mixed="true"
xdb:SQLType="CLOB" xdb:maintainDOM="true">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded"
processContents="skip"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="phoneType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\(\d{3}\)\d{3}-\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

Глядя на этот пример, первая вещь, которую надо сделать при аннотировании XML схемы состоит в том, чтобы включить объявление пространства имен Oracle XML DB xmlns:xdb=”http://xmlns.oracle.com/xdb” в элемент <schema>. Префикс этого пространства имен затем используется, чтобы квалифицировать все аннотации Oracle XML DB.

Далее, xdb:storeVarrayAsTable=”true”, - это глобальная XML DB аннотация, которая говорит XML DB сохранить все элементы VARRAY во вложенных (nested) объектных таблицах. Эта аннотация способствует ускорению запросов к XML элементам, которые определены с помощью maxOccurs>1. Например, в customer_simple_ann.xsd эта аннотация влияет на сохранение элементов <ADDRESS>.

Далее, вы можете определить аннотацию XML DB xdb:mapUnboundedStringToLob=”true” в элементе <schema>, чтобы установить соответствие х строк в CLOB и безразмерных двоичных данных в BLOB при табличном хранении “вне строки” (out-of-online). По умолчанию установлено значение false. Таким образом, все безразмерные строки определены в XML схеме и отображаемы в VARCHAR2(4000), а безразмерные двоичные данные отображены в RAW(2000) при табличном хранении “в строке” (inline). Но, коль скоро inline-таблицы перестали быть эффективным средством для хранения больших XML документов, нужно устанавливать xdb:mapUnboundedStringToLob=”true”.

Для всех глобальных сложных и для простейших типов можно определить следующие аннотации XML DB, которые специфицируют соответствующие SQL имена и типы данных:

  • xdb:SQLType -
  • Определяет SQL тип, отображающий определение типа XML схемы. Эту аннотацию следует использовать во избежание присваивания сгенерированных XML DB имен типам данных SQL.
  • xdb:maintainDOM –
  • Определяет, должен ли сложный тип поддержать DOM точность. В нормальном режиме нужно установить аннотацию в false. Иначе, по умолчанию XML DB будет добавлять атрибут SYS_XDBPD$ (дескриптор позиции) в каждый созданный объектный тип для сохранения такой информации, как: комментарии, инструкции обработки и общие (sibling букв. - имеющие общего "родителя" – словарь Lingvo) элементы упорядоченност в XML, что, тем самым, увеличивает затраты на хранение. Например, для того, чтобы не применять DOM точность в записях о клиентах, устанавливается xdb:maintainDOM=”false” в CustomerType.
ЗАМЕЧАНИЕ

xdb:SQLName не разрешается в описаниях complexType и simpleType. Иначе, вы получите следующую ошибку:

ORA-30937: No schema definition for ‘SQLName’
(ORA_30937. Нет описания схемы для ‘SQLName’) 

(пространство имен ‘http://xmlns.oracle.com/xdb’) в родительском ‘complexType’.

В корневом элементе XML документа нужно специфицировать атрибут xdb:defaultTable и опционально использовать xdb:tableProps для установки атрибутов таблицы:

  • xdb:defaultTable -
  • Специфицирует имя таблицы, в которой может быть сохранен XML экземпляр этой схемы. Он устанавливает связь между репозиторием XML DB и этой таблицей, таким образом, любая вставка, обновление и удаление XML документа, согласующегося с этой XML схемой в этом репозитории XML DB, будет иметь соответствующее изменение в default таблице и наоборот. В примере таблица customer будет создана как default таблица.
  • xdb:tableProps -
  • Специфицирует свойства default таблицы в синтаксисе SQL, что дописано в конец предложения CREATE TABLE.

Для всех XML элементов должно специфицировать имя и тип элемента, если их базовый тип не содержится среди глобальных типов, описанных в XML схеме, которая была аннотирована. Следующий список XML DB аннотаций для XML элементов:

  • xdb:SQLName
  • - Специфицирует имя SQL объекта, который отображает XML элемент
  • xdb:SQLType -
  • Специфицирует имя SQL типа, соответствующего XML элементу xdb:SQLInline – Специфицирует, требуется ли Oracle XML DB генерировать новую объектную таблицу и определять XMLType REFs для сохранения XML элементов. Настройка по умолчанию - true, то есть, REF'ы не определяются. Значение true этой аннотации затрагивает все элементы верхнего уровня, декларированные в XML схеме и XML элементу с maxOccures > 1. Для хранения в режиме “out-of-online” необходимо изменить значение на false. Это повысит производительность зп счет устранения блокировок таблиц.
  • xdb:SQLCollType -
  • Специфицирует имя типа SQL коллекции, соответствующей XML элементу, который имеет maxOccurs > 1. Например, в элементе <ADDRESS> добавлен xdb:SQLCollType=”ADDRESS_TYPE”. По умолчанию коллекция (the collection) использует VARRAY. Поскольку установлено xdb:storeVarrayAsTable=”true”, местом хранения VARRAY является Ordered Collections in Table (OCT) в отличие от LOB (по умолчанию). Это полезно, когда желательно создать ограничения целостности на элемент.

В отличие от запоминания всех возможных аннотаций, мы делаем список наиболее используемых XML DB аннотаций. В итоге, когда аннотируются XML схемы, надо иметь в виду следующее.

Во-первых, необходимо специфицировать имя default таблицы, используя xdb:defaultTable и SQL имя для каждого XML элемента и типа данных в XML схеме, для чего используются xdb:SQLName, xdb:CollType или xdb:SQLType. Следует заметить, что в примере:

  • xdb:SQLName
  • описывает SQL имена для XML элементов
  • xdb:CollType
  • описывает SQL имена только для XML элементов со значением maxOccurs > 1
  • xdb:SQLType
  • описывает SQL имена для всех complexType и simpleType, которые не используют отображение по умолчанию, предусмотренное Oracle XML DB

Определение SQL имен, используя аннотации XML схемы, полезно, потому как сгенерированные системой имена запомнить не просто. Конечно же, должно учитывать определение всех SQL имен, напечатанных прописными буквами для исключения имен с учетом регистра в базе данных, которые требуют использования двойных кавычек при обращении к объектам SQL. Например, без преобразования букв в прописные надо писать “Customer260_TAB”, а не CUSTOMER260_TAB при обращении к default таблице, хранящей записи о клиентах.

ЗАМЕЧАНИЕ

Для XML документов и типов, если не используются xdb:SQLName, xdb:CollType или xdb:SQLType, Oracle XML DB будет использовать имя элемента или типа данных для создания SQL имени. Так как XML регистро-зависим, то и SQL имя будет регистро-зависимым, требуя повсюду использования кавычек для ссылки на них. Эта аннотация также полезна, если имя XML типа или элемента длинное или есть конфликт имен в XML схеме.

Далее следует определить хранение, минимизируя любое дополнительное сохранение данных, избегая, например, хранение DOM точности. Это же надо иметь в виду при организации хранения поддеревьев и сложных типов, как CLOB’ы, когда нет нужды в XPath запросах по контенту, устанавливая xdb:SQLTypes=”CLOB”. Oracle XML DB не будет делить эти XML данные, сохраняя, таким образом, время и ресурсы.

Наконец, когда обрабатываются малые, но безразмерные XML элементы, нужно сохранять контент, как VARRAY, используя установку xdb:storeVarrayAsTable=”false”. Для больших безразмерных элементов можно использовать вложенные таблицы, в элементе <schema> специфицируя xdb:storeVarrayAsTable=”true”, или использовать вложенные таблицы, установив для лучшего выполнения на элемент xdb:maintainOrder=”false”.

Загрузка XML данных

После того, как определено хранение XMLType, можно загружать данные в XMLType таблицы, используя SQL, а именно протокол API или утилиту SQL*Loader.

Использование SQL команд

Простейший способ для загрузки XML данных в XMLType таблицы - использование команды INSERT SQL, как это показано на следующем примере:

INSERT INTO customer VALUES(XMLType('<Customer>
<NAME>Steve Joes</NAME>
<EMAIL>Steve.Joes@example.com</EMAIL>
<ADDRESS>Someroad, Somecity, Redwood Shores, CA 94065, U.S.A</ADDRESS>
<PHONE>6505723456</PHONE>
<DESCRIPTION>Very Important US Customer</DESCRIPTION>
</Customer>').CreateSchemaBasedXML(
'http://localhost:8080/public/contact_simple_ann.xsd'));

Используя этот подход, можно сконструировать XMLType экземпляр из XML в VARCHAR2, CLOB или BFILE и опционально использовать функцию XMLType.CreateSchemaBasedXML() для обращения к зарегистрированной схеме.

Не применяя функцию XMLType.CreateSchemaBasedXML(), можно вставить XML в XMLTypes, базированных на XML Schema, âêëþ÷àÿ XML Schema ссылку на корневой элемент XML документа, используя атрибуты размещения XML схемы, среди которых имеются xsi:schemaLocation и xsi:noNamespaceSchemaLocation:

INSERT INTO customer

values(XMLType('<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema
-instance" xsi:noNamespaceSchemaLocation="http://localhost:8080/public/
contact_simple_ann.xsd">
<NAME>Steve Joes</NAME>
<EMAIL>Steve.Joes@example.com</EMAIL>
<ADDRESS>Someroad, Somecity, Redwood Shores, CA 94065, U.S.A</ADDRESS>
<PHONE>6505723456</PHONE>
<DESCRIPTION>Very Important US Customer</DESCRIPTION>
</Customer>'));

Атрибут xmlns:xsi=”http://www.w3.org/20041/XMLSchema-instance” объявляет пространство имен для экземпляра XML Schema. Атрибут xsi:noNamespaceSchemaLocation=
”http://localhost:8080/public/contact_simple_ann.xsd”
специфицирует URL зарегистрированной XML схемы. В этом примере, если XML документы не обладает пространством имен, используется xsi:noNamespaceSchemaLocation. Если XML документ содержит пространство имен, например, XML схема для XML документа определяет целевое пространство имен как targetNamespace=”http://www.example.com/customer”, тогда необходимо использовать атрибут xsi:schemaLocation, как показано ниже:

xsi:schemaLocation= "http://www.example.com/customer
http://localhost:8080/
public/contact_simple_ann.xsd"

Атрибут содержит targetNamespace, http://example.com/customer и URL XML схемы http://localhost:8080/public/contact_simple_ann.xsd.

Использование интерфейсов репозитория Oracle XML DB

Репозиторий XML DB поддерживает протоколы взаимодействия, включая FTP и WebDAV/HTTP, используемых для вставки XML и других типов документов. Как уже говорилось в Главе 8, вы можете создать папку WebDAV и использовать ее для копирования или редактирования XML файлов в репозитории XML DB, как если бы это была еще одна директория на вашем диске. Когда используются протоколы взаимодействия, XML документ должен иметь атрибуты расположения XML схемы для гарантии того, что данные вставятся в default таблицы, созданные при регистрации XML схемы. В следующем примере используется FTP интерфейс для вставки записей о клиентах в default таблицу customer после регистрации contact_simple_ann.xsd в XML DB:

D:\>ftp

ftp> open localhost 2100
Connected to [Machine_Name] 220 [Machine_Name].FTP Server (Oracle XML
DB/Oracle Database 10g Enterprise Edition Release X.X.X.X.X) ready.
User ([Machine_Name]:(none)): demo
331 pass required for DEMO
Password:
230 DEMO logged in
ftp> cd public
250 CWD Command successful
ftp> put customer1.xml
200 PORT Command successful
150 ASCII Data Connection
226 ASCII Transfer Complete
ftp: 444 bytes sent in 0.00Seconds 444000.00Kbytes/sec.
ftp> ls customer1.xml
200 PORT Command successful
150 ASCII Data Connection
customer1.xml
226 ASCII Transfer Complete
ftp: 15 bytes received in 0.00Seconds 15000.00Kbytes/sec.
ftp>bye

После этих операций новая запись о клиенте вставляется как в репозиторий XML DB в директорию /public, так и в default таблицу customer. В дополнение к двум записям, вставленным с помощью SQL, теперь существует третья запись в таблице customer:

SQL> SELECT count(1) FROM customer;
COUNT(1)
----------
3

Мы обсудим возможности репозитория XML DB в секции “Репозиторий Oracle XML DB”. А сейчас пока требуется знать только, что не важно, какая директория в репозитории XML DB используется для хранения XML документа, новая запись о клиенте будет всегда вставляться в default XMLType таблицу на такой срок, который потребуется для отправки по соответствующему URL зарегистрированной XML схемы.

Использование SQL*Loader

SQL*Loader был широко распространенным инструментом для загрузки данных в базу данных Oracle. В Oracle Database 10g SQL*Loader помогает загружать XML данные в XMLType столбцы или XMLType таблицы, независимо от лежащей в основе памяти хранения. Другими словами, можно использовать один и тот же метод для загрузки XML данных в CLOB или в объектно-реляционный XMLType. Кроме того, SQL*Loader позволяет загрузку XML данных, используя оба метода: традиционный и прямой загрузки. Традиционный путь - это метод по умолчанию, который использует SQL для загрузки данных в базу данных Oracle. Прямой путь обходит SQL и погружает данные непосредственно в файлы базы данных Oracle.

Для загрузки XML данных, используя SQL*Loader, необходимо применять управляющий файл, описывающий входные данные и целевую таблицу и столбцы таблицы. Например, для вставки двух записей о клиентах: customer3.xml и customer4.xml, в таблицу customer, следует создать управляющий файл, как показано далее:

LOAD DATA
INFILE *
INTO TABLE customer
APPEND
XMLType(XMLDATA)(
lobfn FILLER CHAR TERMINATED BY ',',
XMLDATA LOBFILE(lobfn) TERMINATED BY EOF
)
BEGINDATA
xml/customer3.xml,
xml/customer4.xml

Управляющий файл сообщает SQL*Loader, что загружаемые данные (LOAD DATA) содержатся в управляющем файле (INFILE*) добавляются в конец (APPEND) таблицы customer (INTO TABLE customer). XMLType (XMLDATA) ссылается на новые данные как XMLType. До тех пор пока эта операция является дописывающей (appending), SQL*Loader будет загружать новые данные без перезаписывания старых записей о клиентах. Если же вместо этого использовать REPLACE, то старые записи будут удалены перед вставкой новых данных.

Оператор lobfn - это поле FILLER. В SQL*Loader поля FILLER используются для собирания данных из входых строк. Другими словами, поля FILLER не относятся ни к одному столбцу таблицы; вместо этого они используются для пропуска или выбора данных из входного потока. В данном примере lobfn используется для получения имен XML документов после BEGIN DATA, имена разграничиваются запятыми (TERMINATED BY ‘,’). Актуальные XML данные в файлах разделяются символом “конец файла” [end-of-file] (EOF).

После того как управляющий файл будет создан, следует дополнить [переменную] среды PATH директорией $ORACLE_HOME\bin, а затем запустить выполнить команду, чтобы запустить sqlldr – утилиту командной строки SQL*Loader:

D:\>sqlldr userid=demo/demo control=customerLoad.ctl
SQL*Loader: Release X on Thu Jun 26 22:26:53 2003
(c) Copyright 2001 Oracle Corporation. All rights reserved.
Commit point reached - logical record count 2

Userid определяет имя и пароль для пользователя базы данных, которому принадлежит таблица customer. Опция control определяет имя управляющего файла. Результат показывает, что две логических записи были распознаны SQL*Loader. Последующая информация о [выполнении] sqlldr может быть найдена в файле <control_file_name>.log. Можно определить direct=y, если требуется использовать прямой способ загрузки XML данных. В сравнении с традиционным, прямой способ быстрее, так как он обходит SQL уровень и продвигает XML данные в файлы базы данных Oracle без запуска дополнительных процедур или принудительной проверки.

Проверка достоверности XML схемы

В процессе загрузки XML или после обновления контента в XMLTypes, базирующихся на XML Schema, Oracle XML DB просто проверяет, правильно расширяется XML документ с проверками объектов, вместо выполнения проверки достоверности всей XML Schema. Другими словами, Oracle XML DB выполняет только ограниченные проверки для того, чтобы удостовериться, что XML документ согласуется с объектно-реляционным хранением. Например, XML DB проверит, существал ли элемент <PHONE> до вставки записей о клиентах. Это не остановит вставку данных, если номера телефонов нарушают шаблон строки, определенный в XML схеме.

Для очистки от неправильных данных, которые могут быть вставлены в XMLTypes, необходимо явно запрашивать проверку достоверности XML Schema. Простейший способ это сделать - до выполнения операций INSERT создать TRIGGER, как показано ниже:

CREATE OR REPLACE TRIGGER customer_insert
AFTER INSERT ON customer
FOR EACH ROW
DECLARE
doc XMLType;
BEGIN
doc := :new.SYS_NC_ROWINFO$;
XMLType.schemaValidate(doc);
END;

Если только триггер задействован, проводится полная проверка достоверности всякий раз, когда вставляются данные в таблицу customer:

INSERT INTO customer VALUES(
XMLType('<CUSTOMER xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://localhost:8080/public/
contact_simple_ann.xsd">
<NAME>Steve Joes</NAME>
<EMAIL>Steve.Joes@example.com</EMAIL>
<ADDRESS>Someroad, Somecity, Redwood Shores, CA 94065, U.S.A</ADDRESS>
<PHONE>6505723456</PHONE>
<DESCRIPTION>Very Important US Customer</DESCRIPTION>
</CUSTOMER>'));

Таким образом, этот пример вернет следующие ошибки:

INSERT INTO customer
*
ERROR at line 1:
ORA-31154: invalid XML document
ORA-19202: Error occurred in XML processing
LSX-00333: literal "6505723456" is not valid with respect to the pattern
ORA-06512: at "SYS.XMLTYPE", line 333
ORA-06512: at "DEMO.CUSTOMER_INSERT", line 5
ORA-04088: error during execution of trigger 'DEMO.CUSTOMER_INSERT'

Как можно видеть, сообщение об ошибке утверждает, что номер телефона не следует шаблону строки, определенному в XML схеме. После того, как вы обновили номер телефона, можно попробовать снова:

SQL> INSERT INTO customer VALUES(
XMLType('<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://localhost:8080/public/
contact_simple_ann.xsd">
<NAME>Steve Joes</NAME>
<EMAIL>Steve.Joes@example.com</EMAIL>
<ADDRESS>Someroad, Somecity, Redwood Shores, CA 94065, U.S.A
</ADDRESS>
<PHONE>(650)572-3456</PHONE>
<DESCRIPTION>Very Important US Customer</DESCRIPTION>
</CUSTOMER>'));

Добавлена новая правильная запись о клиенте. Следует проверить статус проверки достоверности XML Schema äëÿ объекта XMLType, используя функцию XMLType.isSchemaValid() или функцию XMLType.isSchemaValidated():

SQL> SELECT x.isSchemaValid() FROM customer x;
X.ISSCHEMAVALID()
-----------------
                1
                0
             ...0

Предыдущий результат показывает, что есть только одна запись в таблице и она правильная по XML схеме. Записи, вставленные до этого, не имели статуса valid (правильная). Это так потому, что функция XMLType.schemaValidate() проверяет на достоверность объект XMLType и обновляет статус достоверности объектов XMLType в XML DB.

ЗАМЕЧАНИЕ

Включив полную проверку достоверности получим значительный негативный эффект при выполнении INSERT, таким образом, это следует использовать только в случае необходимости. Обычно лучше проводить проверку достоверности во время создания документа или на среднем уровне(middle tier).

Часть 2

Репозиторий Oracle XML DB

Репозиторий Oracle XML DB может функционировать как файловая система в базе данных Oracle. Любые данные репозитория Oracle XML DB отображаются на ресурсы, которые имеют путевое (pathname – составное) имя (или URL) и сохранены в BLOB или в объекте XMLType. Репозиторий XML DB предоставляет возможность исчерпывающего управления этими ресурсами.

Вы уже изучили, как загружать XML с помощью протокола интерфейсов репозитория XML DB. В этой секции мы обсудим другие темы: возможность версии контролировать документы и созданные связи, управление ресурсами. Мы также обсудим основные PL/SQL пакеты, обеспечивающие эту функциональность:

  • DBMS_XDB
  • обеспечивает функции управления ресурсами и сессиями репозитория XML DB. Так же обеспечивается функциональность перестроения иерархических индексов.
  • DBMS_XDB_VERSION
  • предоставляет функции для контроля версий ресурсов
Управление ресурсами

В Oracle Database 10g вы можете использовать модуль DBMS_XDB для создания и удаления ресурсов, папок-фолдеров и связей ресурсов. Вы также можете использовать этот модуль для блокирования/разблокирования ресурсов во время чтения или обновления XML данных:

DECLARE
res BOOLEAN;
xr REF XMLType;
x XMLType;
BEGIN
FOR po_rec IN (SELECT rownum id, ref(p) xref FROM customer p
ORDER BY rowid)
LOOP
res:=DBMS_XDB.createResource('/public/customer'||po_rec.id||
'.xml', po_rec.xref);
END LOOP;
END;

В этом примере все записи о клиентах считываются из таблицы customer и ресурсные XML документы, созданные в директории /public репозитория XML DB, используют функцию DBMS_XDB.createResource(). Дополнительно в репозитории XML DB можно создать папку /public/important_customer, как показано ниже:

DECLARE
retb BOOLEAN;
BEGIN
retb := DBMS_XDB.createFolder('/public/important_customer');
COMMIT;
END;
/

Далее, можно создать некий ресурс README.txt для отображения содержимого этой папки:

DECLARE
res BOOLEAN;
BEGIN
res :=
DBMS_XDB.createResource('/public/important_customer/README.txt',
'This folder lists all of the US customer who are important to
our business');
COMMIT;

END; /

 

С того момента как создан в директории /public список клиентов, можно создать набор связей, вместо создания второй копии данных:

EXEC DBMS_XDB.link('/public/customer1.xml',
'/public/important_customer/','SteveJones.xml');

Если вы хотите удалить ресурс, можно использовать функцию DBMS_XDB.DeleteResource():

DBMS_XDB.DeleteResource
('/public/important_customer/SteveJones.xml');
DBMS_XDB.DeleteResource ('/public/customer1.xml');

Вы можете удалить ресурс с ресурсными на него связями. Разумеется, после перемещения оригинального ресурса все связанные ресурсы более с ним не связаны. Каждый из них вместо этого будет содержать копию данных.

Контроль версий

Пакеты DBMS_XDB_VERSION и DBMS_XDBPL/SQL обеспечивают функцию контроля версий Oracle XML DB, которая дает способ создания и управления различными версиями Version-Control Resource (VCR) в Oracle XML DB.

Когда XML DB ресурс встроен в VCR, некий флажок маркирует его как VCR, и текущий ресурс становится исходной версией. Эта версия физически не сохраняется в базе данных. Другими словами, нет дополнительной копии этого ресурса, сохраненной, когда он был сделан версией. Следующие версии сохраняются в тех же таблицах. Коль скоро версия ресурса становится системно-сгенерированной, она лишается составного (pathname) имени. Но вы все еще можете получить доступ к ресурсу через функцию, предоставленную в пакете DBMS_XDB_VERSION.

Когда проверяется ресурс, ни какой другой пользователь не может его обновить. Когда ресурс обновляется впервые, создается его копия. Вы можете сделать несколько изменений ресурса без обратного эффекта. Вы всегда будете получать последние версии ресурса, даже если у вас есть различные пользователи. Когда ресурс перезапускается, оригинальная версия, которая заканчивает работу, помещается на место обычного постоянного хранения.

Характеристики версий для VCR содержатся в репозитории XML DB. В этом релизе версионность работает только для небазируемых на схемах (non-schema-based) ресурсах. Таким образом, XMLType, базируемые на раздельных XML-документах, и XMLType CLOB, которые обладают присоединенными схемами, официально не поддерживают использование VCR. Тем не менее, мы обнаружили, что до тех пор, пока вы не создадите уникальные метаданные, ассоциированные с конкретной версией, например индексы, VCR будут работать.

ЗАМЕЧАНИЕ

Вы не можете переключиться с VCR на не-VCR.

Oracle XML DB предоставляет функции для отслеживания всех изменений в VCR Oracle XML DB. Следующий код демонстрирует эти функции:

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
resid := DBMS_XDB_VERSION.MakeVersioned('/public/important_customer/
SteveJones.xml');
END;
/

Вы можете получить идентификатор ресурса VCR:

SET AUTOPRINT ON
VAR OUT CLOB
DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
res XMLType;
BEGIN
resid := DBMS_XDB_VERSION.MakeVersioned
('/public/important_customer/SteveJones.xml');
-- Obtain the resource
res := DBMS_XDB_VERSION.GetResourceByResId(resid);
SELECT res.getClobVal() INTO :OUT FROM dual;
END;

Для обновления VCR вам понадобится проверить ресурс, выполнить обновление файлов и затем вернуть их в репозиторий XML DB:

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
DBMS_XDB_VERSION.CheckOut('/public/important_customer/SteveJones.xml');
resid :=
DBMS_XDB_VERSION.CheckIn('/public/important_customer/SteveJones.xml');
END;

Заметим, что ресурсы не обновятся до тех пор, пока проверяется новый файл. Если вы хотите завершить проверку, вы можете “распроверить” ресурс:

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
resid :=
DBMS_XDB_VERSION.UncheckOut
('/public/important_customer/SteveJones.xml ');
END;
Сохранение XML документов в реляционных таблицах

Реляционные таблицы обычно проектируются, не принимая во внимание хранение XML. Однако во многих случаях эти таблицы могут быть использованы для сохранения расщепленных (shredded) XML-документов и порождения полезных XML-отображений с помощью создания XMLType-представлений, использующих XML-опции Oracle Database 10g, или генерирующих XML с использованием Oracle XDK.

Хранение XML-данных в реляционных таблицах удобно, если вашему приложению нужно избавиться от таких ограничений XMLType-хранения, как ограничение на эволюцию XML-схемы или реплицирование данных. Реляционное хранение также широко используется приложениями, которые нуждаются в низко уровневом доступе к данным из XML- документов, пока не требуется защита полной иерархической структуры XML.

Oracle Database 10g предоставляет обширную поддержку для загрузки, экспортирования и обработки XML-данных в реляционных таблицах. Для загрузки XML-данных вы можете использовать утилиту XML SQL Utility (XSU), которая обеспечивает оба: Java и PL/SQL программных интерфейса, а также утилиты командной строки. Утилита TransX Utility (Translation XML), построенная на XSU, упрощает дальнейшее преобразование набора символов (character set) перед загрузкой данных, а XSQL Servlet предоставляет HTTP-интерфейсы. Если для вашего приложения недостаточно функциональности, предлагаемой данными утилитами, вы можете использовать их программный API в объединении с другими библиотеками XDK для построения собственного решения.

Утилита XML SQL Utility

XSU предлагает API, базируемые на Java, утилиты командной строки и PL/SQ-пакеты, которые поддерживают загрузку XML-данных в реляционные таблицы, включая таблицы, содержащие столбцы XMLType. Мы в следующих разделах рассмотрим, как можно использовать эту функциональность.

Каноническое отображение

Первое, что вам следует сделать перед использованием XSU, это понять, будет ли использоваться каноническое отображение XSU для отображения XML в реляционные таблицы и визуализировать результаты SQL-запросов в XML. В данном каноническом отображении элемент <ROWSET> является корневым элементом XML-документа, а его дочерние элементы <ROW> отображаются в столбцы данных в таблицах. Имена дочерних элементов для каждого элемента <ROW> отображаются в имена табличных столбцов или имена объектов, из которых возвращаются результаты. Атрибуты num элементов <ROW> являются номерами, по которым доступна заказанная информация. Далее следует пример отображения XML-схемы этой структуры метаданных:

><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="ROWSET">
<xs:complexType>
<xs:sequence>
<xs:element name="ROW">
<xs:complexType>
<xs:sequence>
<xs:any/>
</xs:sequence>
<xs:attribute name="num" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

XSU предоставляет способы изменения имен элементов <ROWSET> и <ROW>. Например, таблица CUSTOMER_TBL определятся так:

CREATE TABLE CUSTOMER_TBL (
NAME VARCHAR2(100),
ADDRESS VARCHAR2(200),
EMAIL VARCHAR2(200),
PHONE VARCHAR2(50),
DESCRIPTION VARCHAR2(4000));

XML-документ отображается в таблицу каноническим отображением, как показано далее:

<ROWSET>
<ROW>
<NAME>Steve Jones</NAME>
<EMAIL>Steve.Jones@example.com</EMAIL>
<ADDRESS>Someroad, Somecity, Redwood Shores, CA 94065, U.S.A</ADDRESS>
<PHONE>6505723456</PHONE>
<DESCRIPTION>Very Important US Customer</DESCRIPTION>
</ROW>
</ROWSET>
ЗАМЕЧАНИЕ

По умолчанию все имена таблиц, столбцов и объектов пишутся на верхнем регистре. Таким образом, если вы хотите правильно вставить XML-документ со смешанными регистрами, то вам необходимо специфицировать опции ignoreCase во время использования XSU.

Чтобы надлежащим образом запустить XSU утилиту из командной строки, вам нужно установить следующие Java-пакеты в ваш Java CLASSPATH:

  • xmlparserv2.jar
  • Oracle XML Parser для Java
  • classes12.jar
  • Oracle JDBC драйверы
  • xsu12.jar
  • Oracle XML SQL Utility
ЗАМЕЧАНИЕ

Вам может понадобиться вставить пакет orai18n.jar в ваш Java CLASSPATH, когда оперируете XML с различными наборами символов. Иначе вы можете получить oracle.xml.sql.OracleXMLSQLException: ‘java.sql.SQLException: Non supported character set…’

XSU зависит от синтаксического анализатора XML, чтобы построить DOM, а также зависит от JDBC-драйвера для подключения к базе данных Oracle и извлечения мета данных. После того как Java CLASSPATH установлен должным образом, вы можете запустить утилиту командной строки XSU с помощью java OracleXML, которая имеет две опции: getXML для запросов к базе данных и putXML для добавления данных в базу данных.

ЗАМЕЧАНИЕ

Операции обновления и удаления не включены в утилиту командной строки XSU, но они поддерживаются Java и API PL/SQL.

Например, для добавления XML-данных в contact01.xml можно задействовать следующую команду:

java OracleXML putXML -conn "jdbc:oracle:thin:@localhost:1521:orclX"

-user "demo/demo" -fileName "customer1_xsu.xml" "customr_tbl"

Данные добавлены в таблицу CUSTOMER_TBL в схеме demo. Для запроса содержимого таблицы и возвращения результатов в XML можно задействовать следующую XSU команду:

java OracleXML getXML -conn "jdbc:oracle:thin:@localhost:1521:orclX"

-user "demo/demo" "SELECT * FROM customer_tbl"

Возвращается следующий XML-документ:

<?xml version = '1.0'?>
<ROWSET>
<ROW num="1">
<NAME>Steve Jones</NAME>
<ADDRESS>Someroad, Somecity, Redwood Shores, CA 94065, U.S.A</ADDRESS>
<EMAIL>Steve.Jones@example.com</EMAIL>
<PHONE>6505723456</PHONE>
<DESCRIPTION>Very Important US Customer</DESCRIPTION>
</ROW>
</ROWSET>

В этом случае данные XML-документа успешно загружены в база данных. Однако добавляемые XML-документы не всегда находятся в каноническом формате. Как следует обращаться с такими документами? Обычный прием - это использование XSLT-таблицы стилей для трансформирования XML-документа в канонический формат. С другой стороны, вы можете создать объектные представления в базе данных, отображающих входной XML-формат.

Объектные представления

Если XML-документ не находится в каноническом формате, вы можете создать объектные представления или XMLType-представления, чтобы позволить XSU отображать XML-документы в таблицы базы данных. Как показано далее, контактная информация сохраняется в следующем contact.xml XML-документе:

<Contact_List>
<Contact>
<User_id>userid</User_id>
<First_Name>Steve</First_Name>
<Last_Name>Jones</Last_Name>
<Business>
<Email>Steve.Jones@oracle.com</Email>
<Phone>(650)5769801</Phone>
<Address>
<Street1>4op11</Street1>
<Street2>500 Oracle Parkway</Street2>
<City>Redwood Shores</City>
<State>CA</State>
<Zipcode>94065</Zipcode>
<Country>USA</Country>
</Address>
</Business>
</Contact>
</Contact_List>

Схема базы данных определяется, как показано далее:

CREATE TYPE address_typ AS OBJECT(
street1 VARCHAR2(200),
street2 VARCHAR2(200),
city VARCHAR2(100),
state VARCHAR2(20),
zipcode VARCHAR2(20),
country VARCHAR2(20));
/
CREATE TABLE contact_tbl(
contactid VARCHAR2(15) PRIMARY KEY,
firstname VARCHAR2(100),
lastname VARCHAR2(200),
midname VARCHAR2(50),
business_phone VARCHAR2(20),
home_phone VARCHAR2(10),
cell_phone VARCHAR2(20),
business_addr address_typ,
business_email VARCHAR2(150));

Используя каноническое отображение, XML-документ не может напрямую отобразится в столбцах таблицы, как документ, содержащий несколько уровней. Таким образом, для того, чтобы вставить XML-документ, нужно создать следующее объектное представление:

CREATE TYPE contactinfo_type AS OBJECT(
phone VARCHAR2(20),
email VARCHAR2(150),
address address_typ);
/
-- Create Object View
CREATE VIEW contact_view AS
SELECT contactid AS user_id, firstname AS first_name, lastname AS
last_name,midname AS mid_name,
contactinfo_type(business_phone,business_email,
business_addr) AS business
FROM contact_tbl;

Далее вы можете запустить следующую команду для загрузки XML-файла в CUSTOMER_VIEW:

java OracleXML putXML -conn "jdbc:oracle:thin:@localhost:1521:orclX"
-user "demo/demo" -fileName "contacts.xml" "contact_view"

В данном примере contact_view используется база данных Oracle для отображения XML- данных в базовые таблицы. Однако, во многих случаях эти типы представлений не будут обновляемыми, когда они содержат многоуровневые таблицы соединения или объекты типа наследования. Далее для обращения с совокупностью данных в этих таблицах и объектов вы должны создать INSTEAD-OF-TRIGGERS для представлений.

Деление XML-документов на фрагменты

Когда сохраняете XML-документ, вы иногда не хотите отображать каждый XML-элемент в столбцах реляционной таблицы. Вместо этого, вы можете захотеть сохранить некоторые XML-фрагменты в XML CLOB или XMLType. Следующий пример иллюстрирует подход в использование XSLT для создания таких XML-фрагментов и вставки этих же XML-фрагментов в один столбец XMLType-таблицы, используя XSU. В примере добавляемый XML-документ представлен как:

<Contact_List>
<Contact>
<User_id>jwang</User_id>
<First_Name>Jinyu</First_Name>
<Last_Name>Wang</Last_Name>
<Title>Senior Product Manager</Title>
<Description>Jinyu manages the <PRODUCT>Oracle XML Developer's
Kit</PRODUCT> product.</Description>
</Contact>
</Contact_List>

Элемент <Description> содержит смешанный контент, который мы не хотим отображать (to map) в несколько столбцов таблицы. Таблицы contact_tbl определяется, как показано далее:

CREATE TABLE contact_tbl(
contactid VARCHAR2(15) PRIMARY KEY,
firstname VARCHAR2(100),
lastname VARCHAR2(200),
midname VARCHAR2(50),
description CLOB);

Для отображения элемента <Description> в столбец description, используя XSU, вам нужно задействовать следующую setCDATA.xsl таблицу стилей XSL:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output cdata-section-elements="CODE"/>
<!-- Identity transformation -->
<xsl:template match="*|@*|comment()|processing-instruction()|
text()">
<xsl:copy>
<xsl:apply-templates select="*|@*|comment()|processing-instruction()|
text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Description">
<xsl:element name="Description">
<xsl:copy-of select="@*|comment()|processing-instruction()"/>
<xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
<xsl:apply-templates select="*|./*/@*|./*/comment()|./*/
processing-instruction()|text()"/>
<xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

Это XSLT-преобразование трансформирует входящий XML-документ и включит все дочерние элементы <Description> в одну секций CDATA, так что каждая секция CDATA может быть сохранена с помощью XSU в столбце description.

Вы можете модифицировать таблицу стилей XSL для вашего приложения, специфицируя различные match-атрибуты по следующему шаблону:

<xsl:template match="Description">… </ xsl:template>

XPath в match-атрибуте специфицирует корневой элемент для сохранения XML-фрагмента.

ЗАМЕЧАНИЕ

Так как XSLT требует, чтобы DOM был встроен в память, вам может потребоваться перед преобразованием разбиение большого документа.

Утилита TransX Utility

Когда происходит заполнение базы данных Oracle многоязычными данными или преобразование данных, или когда происходит кодирование, требуется проверка достоверности каждого XML-файла. Традиционный путь решения - это переключение установки NLS_LANG, как будто вы переключаетесь на загрузку файлов с различными кодовыми таблицами. Параметр NLS_LANG определяет таблицу символов для загруженного в базу данных файла. Этот подход подвержен ошибкам, потому что кодовая информация поддерживается отдельно от самих данных. Постоянно переустанавливать NLS_LANG - очень скучная работа.

При использовании TransX Utility, предусмотренной XDK, кодовая информация содержится вместе с данными в XML-документе в предопределенном формате. Таким образом, многоязыковые данные могут быть перемешены без переключения настройки NLS_LANG. TransX Utility поддерживает корректный набор символов на всем протяжении процесса транслирования данных и успешно загружает его в базу данных. Мы не будем детально рассматривать использование TransX Utility. Но мы рассмотрим некоторые примеры, чтобы вы смогли увидеть ее функциональные возможности.

Пакет DBMS_XMLSTORE

DBMS_XMLSTORE - это PL/SQL-пакет, который обеспечивает добавление XML-данных в таблицы базы данных. Эта C-базированная реализация обеспечивает лучшую производительность и системную управляемость, чем Java-базированный пакет DBMS_XMLSave. Этот пакет устраняет накладные издержки в начале работы Oracle JVM такие, как транслирование имен Java-классов при каждом вызове методов. Кроме того, DBMS_XMLSTORE построен на основании анализатора SAX, а не на анализаторе DOM. Соответственно, он лучше масштабирует большие XML-документы. Вы можете заметить это в следующем сопоставлении, используя эталонную схему SH:

SQL> SELECT count(1) FROM sales;
COUNT(1)
----------
1136945
SQL> CREATE TABLE test AS SELECT * FROM sales;
Table created.
SQL> CREATE TABLE result AS SELECT * FROM sales WHERE 0=1;
Table created.
SQL> SELECT count(1) FROM test;
COUNT(1)
----------
1136945
SQL> SELECT count(1) FROM result;
COUNT(1)
----------
0
SQL> SET timing ON
SQL> DECLARE
2 qryCtx DBMS_XMLQuery.ctxHandle;
3 v_clob CLOB;
4 savCtx DBMS_XMLSave.ctxType;
5 v_rows NUMBER;
6 BEGIN
7 -- Query out the content
8 qryCtx := DBMS_XMLQuery.newContext('SELECT * FROM test');
9 v_clob := DBMS_XMLQuery.getXml(qryCtx);
10 DBMS_OUTPUT.PUT_LINE('CLOB size = '||DBMS_LOB.GETLENGTH(v_clob));
11 -- Save the content
12 savCtx := DBMS_XMLSave.newContext('RESULT');
13 v_rows := DBMS_XMLSave.insertxml(savCtx,v_clob);
14 DBMS_XMLSave.closeContext(savCtx);
15 DBMS_OUTPUT.PUT_LINE(v_rows || ' rows inserted...');
16 END;
17 /
DECLARE
*
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception:
java.lang.OutOfMemoryError
ORA-06512: at "SYS.DBMS_XMLSAVE", line 114
ORA-06512: at line 13
Elapsed: 00:11:57.05

В предшествующем примере таблица sales эталонной схемы SH, описанная в Главе 8, используется для формирования большого XML-документа, который, когда анализируется, слишком велик для сконфигурированной памяти хранения Oracle JVM. Вы можете увеличить JAVA_POOL_SIZE, чтобы выделить больше памяти для обработки, однако, это может быть не достаточно, особенно, когда эта память выбирается из пула оперативной памяти базы данных. В Oracle Database 10g вы можете воспользоваться пакетом DBMS_XMLSTORE для разрешения этой проблемы, как показано далее:

DECLARE
v_clob CLOB;
savCtx DBMS_XMLSTORE.ctxType;
v_rows NUMBER;
BEGIN
-- Query out the content
SELECT doc INTO v_clob FROM temp_clob;
-- Save the content
savCtx := DBMS_XMLSTORE.newContext('RESULT');
-- Set the update columns to improve performance
DBMS_XMLSTORE.SetUpdateColumn (savCtx, 'PROD_ID');
DBMS_XMLSTORE.SetUpdateColumn (savCtx, 'CUST_ID');
DBMS_XMLSTORE.SetUpdateColumn (savCtx, 'TIME_ID');
DBMS_XMLSTORE.SetUpdateColumn (savCtx, 'CHANNEL_ID');
DBMS_XMLSTORE.SetUpdateColumn (savCtx, 'PROMO_ID');
DBMS_XMLSTORE.SetUpdateColumn (savCtx, 'QUANTITY_SOLD');
DBMS_XMLSTORE.SetUpdateColumn (savCtx, 'AMOUNT_SOLD');
-- Insert the document
v_rows := DBMS_XMLSTORE.insertxml(savCtx,v_clob);
DBMS_XMLSTORE.closeContext(savCtx);
DBMS_OUTPUT.PUT_LINE(v_rows || ' rows inserted...');
END;

Рекомендуется использовать функцию SetUpdateColoumn() из DBMS_XMLSTORE всегда, когда это подходит, как было в предыдущем примере, потому как это позволяет программе DBMS_XMLSTORE узнать список столбцов, которые должны быть обновлены для использования явного SQL-связывания с XML-данными. Предыдущий пример использует следующее SQL-выражение при подготовке к добавлению данных:

INSERT INTO sales(prod_id, cust_id, ..., amount_sold) values
(:1, :2, ..., :6);

Это ускоряет процесс вставки данных, устраняя накладные расходы от парсинга (parsing – синтаксический анализ) SQL-предложений в базе данных.

Использование внешних таблиц

Появившийся в Oracle9i механизм внешних таблиц предлагает возможность определения таблицы в базе данных, а хранение табличных данных отдельно от нее, вне базы данных. До Oracle Database 10g внешние таблицы могли быть использованы только как таблицы для чтения. Другими словами, если вы создаете внешнюю таблицу для XML-файлов, эти файлы могут быть запрошены, а таблица может быть соединена с другими таблицами. Тем не менее, никакие DML операции: INSERT, UPDATE и DELETE не разрешены во внешних таблицах.

ЗАМЕЧАНИЕ

В Oracle Database 10g можно записывать данные во внешние таблицы, используя драйвер ORACLE_DATAPUMP вместо используемого по умолчанию ORACLE_DRIVER.

В Oracle Database 10g можно определить во внешней таблице столбцы VARCHAR2 и CLOB для сохранения XML-документов. В следующем примере показано, как создается внешняя таблица со столбцом CLOB для хранения XML-документов. Во-первых, вам нужно создать DIRECTORY для чтения фалов данных:

CREATE DIRECTORY data_file_dir AS
'D:\xmlbook\Examples\Chapter9\src\xml';
GRANT READ, WRITE ON DIRECTORY data_file_dir TO demo;

Затем надо использовать DIRECTORY для определения внешней таблицы:

CREATE TABLE customer_xt (doc CLOB)
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY data_file_dir
ACCESS PARAMETERS
(
FIELDS (lobfn CHAR TERMINATED BY ',')
COLUMN TRANSFORMS (doc FROM lobfile (lobfn))
)
LOCATION ('xml.dat')
)
REJECT LIMIT UNLIMITED;

Далее файл xml.dat

customer1.xml
customer2.xml 

Если таблица определена, то можно увидеть следующее:

SQL> DESC customer_xt;
Name Null? Type
----------------------------------------- -------- -------------
DOC CLOB

Затем можно запросить XML-документ, как показано далее:

SELECT XMLType(doc).extract('/Customer/EMAIL')

FROM customer_xt;

Тем не менее, запрос требует время работы на создание XMLType и XPath оценки, этот подход полезен, когда приложения нуждаются лишь в нескольких запросов к XML-данным и не хотят перегружать XML-данные в базу данных. В Oracle Database 10g вы не можете создать внешнюю таблицу, которая содержит предопределенные типы XMLType-столбцов.

Эволюция схем

XML-схем развиваются, когда появляется новые требования для XML-данных. Ваши возможности отображать эти изменения в базе данных во многом зависит от памяти хранения.

Если используются реляционные таблицы, то можно изменить структуру таблицы и обновить XML-представления для отражения нового отображения из XML в реляционные таблицы. Если используются CLOB XMLType, то новые XML-данные могут быть вставлены напрямую, так как эта память позволяет вам согласовано сохранять XML в разных XML-схемах. Однако для XML Schema, базируемых на XMLType, эволюция их схем – это очень дорогостоящий процесс, так как он требует обновления объектно-реляционной структуры XMLType. В Oracle Database 10g этот тип развития ограничен для каждого выполняемого импорта/экспорта данных и использования функции CopyEvolution() из пакета DBMS_XMLSCHEMA.

Наилучшая практика

Если нужно принимать XML-данные и сохранять их в базе данных, то первое, что нужно учесть, - это требует ли ваше приложение заготовки XML-структуры в базе данных. Как мы уже видели в Главе 8, вам нужно взвесить все “за и против” возможностей хранения XML и проанализировать, каким образом хранение повлияет на извлечение и обновление XML-данных. В дополнение, вам иногда нужно выбирать особенную модель XML-хранения для осуществления поддержки получения XML в сочетании с разработкой XML-схемы.

После выбора для вашего приложения правильной модели XML-хранения в следующей секции представлены некоторые указания, что нужно знать, когда XML хранятся в Oracle Database 10g.

Обработка определений типов документов

Хотя DTD не используются для определения структуры памяти хранения для XMLType, Oracle XML DB разрешает все DTD-определения и объекты, определенные или упомянутые во вставленном XML-документе. Это выполняется в процессе вставки XMLType, когда анализируются (parsed) все пришедшие XML-документы. В этом процессе разрешаются все объекты, включая внешние и внутренние, определенные в DTD. Это означает, что все объекты перемещаются вместе со своими реальными значениями и, следовательно, все первоначальные

(оригинальные) объектовые ссылки утрачиваются.

Если вы захотите оставить эти ссылки, вам следует сохранить XML в CLOB, вместо CLOB XMLType. Потом вы можете всякий раз создать временный XMLType из этого CLOB, когда вам понадобится разрешить все объекты и использовать контент XML.

Создание XML Schema-базируемых XMLTypes

 

Вы можете создавать XML Schema-базируемые XMLTypes, используя функции конструирования XMLType или XMLType.CreateXML() функцию. Однако, когда вы используете эти функции для создания XML Schema-базируемых XMLTypes, XML-документ должен содержать XML-атрибуты SchemaLocation. Иногда XML-документ не содержит таких атрибутов. Как же вы сможете создать XML Schema-базируемый XMLType без изменения оригинального XML-документа?

В Главе8 было показано, что можно использовать функцию XMLType.CreateSchemaBasedXML и специфицировать URL XML схемы, как показано ниже:

INSERT INTO product(id, name, description)
VALUES('xdk', 'XML Developer's Kit',
XMLTYPE('<DESCRIPTION><KEYWORD>xdk</KEYWORD> is a set of
standards-based utilities that helps to build
<KEYWORD>XML</KEYWORD> applications. It contains XDK Java
Components, XDK C Components and XDK C++ Components.
</DESCRIPTION>').CreateSchemaBasedXML('http://xmlns.oracle.com/
xml/content.xsd'));

URL http://xmlns.oracle.com/xml/content.xsd является зарегистрированным URL XML схемы и будет использоваться для сохранения продуктового DESCRIPTION.

Специфицирование пространства имен

Если сохраненный XML-документ имеет пространства имен (namespaces), то все XML-запросы к этому документу должны быть определены для пространства имен, так как <Namespace:Element> - это не одно и то же что <Element> в XML. Обе функции XMLType.existNode() и XMLType.extract() разрешают пользователю специфицировать пространство имен во втором параметре, как показано ниже:

MEMBER FUNCTION existsNode(xpath in varchar2, nsmap in varchar2)
RETURN number deterministic
MEMBER FUNCTION extract(xpath IN varchar2, nsmap IN varchar2)
RETURN XMLType deterministic

В этом случае Xpath требует использования полностью квалифицированных (qualified) XML имен, которые содержат имя элемента и его пространство имен. Например, вы можете вставить XML-документ с двумя декларированными пространствами имен в XMLTypes, как показано ниже:

CREATE TABLE temp (doc XMLType);
DECLARE
v_temp XMLType;
BEGIN
v_temp:= XMLType.createXML('<foo xmlns="http://www.example.com"
xmlns:xsd="http://www.w3c.org/2001/XMLSchema">
<foo_type xsd:type="date">03-11-1998</foo_type>
</foo>');
INSERT INTO temp VALUES(v_temp);
END;

Чтобы запросить этот документ, вы можете определить пространство имен и его префикс во втором параметре функции XMLType.extract() и квалифицировать XPath, используя префикс, как показано в следующем SQL-запросе:

SELECT a.doc.extract('/a:foo/a:foo_type',
'xmlns:a="http://www.example.com"')
FROM temp a;

Результатом будет:

<foo_type xmlns="http://www.example.com"
xmlns:xsd="http://www.w3c.org/2001/
XMLSchema" xsd:type="date">03-11-1998</foo_type>
ЗАМЕЧАНИЕ

Если вы не используете квалифицированное имя пространства имен в XPath после предоставленных пространств имен, вы получите [сообщение] ORA-31013: Invalid XPath expression error.

Если у вас есть несколько пространств имен, то можно составить из них список, используя второй параметр функций XMLType.existNode() и XMLType.extract() и разделить их пробелами, как показано в следующем примере:

SELECT a.doc.extract('/a:foo/a:lastupdate/@b:type',
'xmlns:a="http://www.example.com"
xmlns:b="http://www.w3c.org/2001/XMLSchema"') AS result
FROM temp a;
RESULT
--------------------------------------------------
date
ВЫВОДЫ

В этой главе рассматривались разнообразные опции XML-памяти и соответствующие им стратегии загрузки в Oracle Database 10g. Таблица 9-1 показывает взаимодействие между XML-памятью хранения и функциональностью предложенных XML-утилит для загрузки данных. Вы можете выбрать одну из этих утилит или использовать SQL- или PL/SQL- интерфейсы для загрузки XML-документов в базу данных Oracle.

 

Утилиты Функцио- нальность Реляцинное хранилище с XMLType представлениями Таблицы XMLType XMLType столбцы
SQL*Loader Утилита командной строки Ограниченная поддержка Да Да
XML SQL Utility Утилита командной строки и программный Java- и PL/SQL-интерфейс Да Да Да
TransX Utility Утилита командной строки и программный Java- интерфейс Да Да Да
XSQL Servlet Утилита командной строки и программный Java- и HTTP- интерфейсы, подготовленные во встроенных обработчиках Да Да Да
HTTP/WebDAV HTTP/WebDAV директории Нет Да, но таблица требует создания таблицы по умолчанию, до того как XML-схема будет зарегистрирована Нет
FTP Interfaces FTP -интерфейсы Нет Да, но таблица требует создания таблицы по умолчанию, до того как схема будет зарегистрирована Нет

Таблица 9-1. Хранение XML-данных и утилиты загрузки данных



Опубликовал admin
13 Фев, Воскресенье 2005г.



Программирование для чайников.