| « Поставить закладку » « Сделать стартовой » | |||
|
|||
|
Хранение XML данных (Storing XML Data)
Марк Скандина, Бен Чанг, Джайню Ванг Глава 9 из книги "Oracle Database 10g XML & SQL: Design, Build, & Manage XML Applications in Java, C, C++, & PL/SQL" by Mark Scardina, Ben 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:ORACLEADMINORCLXUDUMP И далее, наличие трассировочного файла orclX_ora_<Session_id>.trc в USER_DUPM_DIR можно проверить следующей командой: SQL> host ls d:oracleadminorclXudumporclX_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”. Представленная выше структура показывает что:
Глядя на эту структуру 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). Эти аннотации, главным образом, можно использовать, чтобы определить следующее:
Давайте рассмотрим следующую аннотированную 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:SQLName не разрешается в описаниях complexType и simpleType. Иначе, вы получите следующую ошибку: ORA-30937: No schema definition for ‘SQLName’ (ORA_30937. Нет описания схемы для ‘SQLName’) (пространство имен ‘http://xmlns.oracle.com/xdb’) в родительском ‘complexType’. В корневом элементе XML документа нужно специфицировать атрибут xdb:defaultTable и опционально использовать xdb:tableProps для установки атрибутов таблицы:
Для всех XML элементов должно специфицировать имя и тип элемента, если их базовый тип не содержится среди глобальных типов, описанных в XML схеме, которая была аннотирована. Следующий список XML DB аннотаций для XML элементов:
В отличие от запоминания всех возможных аннотаций, мы делаем список наиболее используемых XML DB аннотаций. В итоге, когда аннотируются XML схемы, надо иметь в виду следующее. Во-первых, необходимо специфицировать имя default таблицы, используя xdb:defaultTable и SQL имя для каждого XML элемента и типа данных в XML схеме, для чего используются xdb:SQLName, xdb:CollType или xdb:SQLType. Следует заметить, что в примере:
Определение 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= 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*LoaderSQL*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_HOMEbin, а затем запустить выполнить команду, чтобы запустить 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 пакеты, обеспечивающие эту функциональность:
Управление ресурсамиВ 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 UtilityXSU предлагает 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:
ЗАМЕЧАНИЕВам может понадобиться вставить пакет 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"><![CDATA[</xsl:text> <xsl:apply-templates select="*|./*/@*|./*/comment()|./*/ processing-instruction()|text()"/> <xsl:text disable-output-escaping="yes">]]></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_XMLSTOREDBMS_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:xmlbookExamplesChapter9srcxml'; 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.
Таблица 9-1. Хранение XML-данных и утилиты загрузки данных Рубрика: XML
HTML 5: пять вещей вызывающих особый интер....
HTML 5 — это грядущее обновление гипертекстового языка разметки, основного способа создания контента для размещения его во всемирной паутине. Разработка HTML остановилась в 1999 году, на версии HTML 4.01 и с тех пор web-содержимое изменилось так, что текущие спецификации HTML перестали соответствовать сегодняшним требованиям. HTML 5 нацелен на то, чтобы увеличить функциональную совместимость HTML и соответствовать растущим требованиям разнообразного и смешанного web-контента. HTML 5 так же нацелен на устранение недостатков четвертой версии. В этой статье мы взглянем на 5 новых интересных вещей в HTML 5.
Подробнее... |
Рубрика: Html
| Добавлено: 22.12.2008
asp.net: ListView с разных сторон.
Элемент управления ListView был представлен в .Net Framework 3.5 как замена устаревшему GridView. Новый элемент имеет более расширенный функционал, чем его предшественник, но в тоже время лишен некоторых внутренних механизмов, что впрочем целиком следствие из расширенной универсальности ListView. Среди отличий ListView и GridView можно назвать и гибкую настройку разметки, что позволяет выводить данные не только в табличном виде, но и вообще в любом каком пожелает программист. Благодаря шаблонам ItemTemplate, EditItemTemplate, InsertItemTeplate можно настроить внешний вид при любом из состояний ListView: редактировании или выборе элемента.
Подробнее... |
Рубрика: .NET компоненты
| Добавлено: 22.12.2008
Создание кросс-таб отчета в Stimulsoft Rep....
Компания Стимулсофт предоставляет для разработчиков мощный набор инструментов для создания отчетов для Microsoft Visual Studio .Net 2005 и 2008; эти инструменты доступны как для Windows Forms, так и для Web Forms. Это генератор отчетов Stimulsoft Reports.Net. Генератор отчетов Stimulsoft Reports.Net имеет ряд особенностей: простая работа с дизайнером отчетов, полная поддержка экспорта в PDF, Word, Excel и многие другие форматы. Crystal Report и Microsoft Reporting Service – очень хорошие программные продукты для повседневной работы, но, если Вам необходимо создать отчеты с поддержкой кросс-табов, drill down, Ajax, штрих-кодов и возможностью подключения одновременно более одного источника данных, то Stimulsoft Reports.Net поможет Вам сэкономить массу времени. Также, данный генератор отчетов позволяет пользователям создавать свои собственные отчеты любой сложности. И все эти особенности делают Stimulsoft Reports.Net хорошим выбором в сфере программных продуктов для Business Intelligence.
Подробнее... |
Рубрика: .NET компоненты
| Добавлено: 22.12.2008
Остальные статьи: |
Цитата дня (все,добавить):
|
Realcoding.NET
© 2003-2008 |
Контакты |
Реклама на сайте
|