Домены
Домены
Для того чтобы преобразовать SQL-домен в XML, вначале этот домен необходимо создать. Для создания домена воспользуемся оператором CREATE DOMAIN:
CREATE DOMAIN WestCoast AS CHAR (2)
CHECK (State IN ('CA\ 'OR1, ' WA' , ' AK ' ) ) ;
Теперь создадим таблицу, которая использует этот домен:
CREATE TABLE WestRegion ( | ||
ClientName | Character (20) | NOT NULL, |
State | WestCoast | NOT NULL |
) ; |
Ниже приведена XML-схема преобразования домена в XML.
<xsd:simpleType>
Name='DOMAIN.SalesWestCoast'>
<xsd:annotation> <xsd:appinfo>
<sqlxml:sqltype kind='DOMAIN'
schemaName='Sales'
typeName='WestCoast'
mappedType='CHAR_2'
finals'true'/>
<xsd:appinfo>
</xsd:annotation>
<xsd:restriction base='CHAR_2'/>
</xsd:simpleType>
После применения этого преобразования вы получите XML-документ примерно следующего содержания:
<WestRegion>
<row>
.
.
.
State>AK</State>
.
.
.
</row>
.
.
.
</WestRegion>
SQL 2003 и XML
Глава 17. SQL:2003 и XML
Как XML связываемся с SQL
Как XML связываемся, с SQL
XML, как и HTML, является языком разметки, а значит, не полнофункциональным языком, как, например, C++ или Java. Это даже не подъязык манипулирования данными, как SQL. Однако он достаточно осведомлен в отношении перемещаемых им данных. Там, где HTML имеет дело только с форматированием текста и графики в документе, XML позволяет работать со структурой содержимого документа. Однако сам XML не предназначен для прямого форматирования. Для осуществления задачи форматирования необходимо дополнить XML таблицей стилей, которая, как и в HTML, позволяет форматировать XML-документы.
SQL и XML структурируют данные двумя различными способами. Таким образом, вы можете сохранить данные и выбрать из них необходимую информацию одним из следующих способов.
SQL представляет собой прекрасный инструмент для работы с числовыми и текстовыми данными, классифицированными по типам данных и имеющими точно описанный размер. Язык SQL был создан как стандартный инструмент для поддержки и работы с данными, хранящимися в реляционных базах данных. Если речь идет о произвольных данных, которые не могут быть однозначно классифицированы, то здесь лучше использовать язык XML. Движущей силой для разработчиков при создании языка XML было стремление обеспечить универсальный стандарт для перемещения данных между разнородными компьютерами и отображения их в World Wide Web.SQL и XML как бы дополняют цели и возможности друг друга. Каждый несет в себе определенные непревзойденные преимущества в отношении собственных альянсов доменов и форм, что позволяет пользователю получить всю необходимую информацию в любое время и в любом месте.
Когда ХМLданные не используются
Когда ХМL-данные не используются
Иногда использование XML-данных не имеет никакого смысла, поскольку сегодня большинство данных в реляционных базах данных гораздо лучше работает в их текущем формате, нежели в формате XML. Для подтверждения вышесказанного приведем два примера. Итак, XML тип не используется в следующих случаях.
При естественном разбиении данных в реляционной структуре на таблицы, строки и столбцы. Если необходимо обновить только некоторые части, а не весь документ.Когда используются XMLданные
Когда используются XML-данные
Необходимость хранения данных в формате XML зависит от того, что вы планируете делать с этим данными. Принятие такого решения целесообразно в следующих случаях.
Если необходимо хранить целый блок данных для последующего получения этих данных в том же полном блоке. Если необходимо сделать запрос для целого XML-документа. Некоторые реализации имеют расширенные возможности оператора EXTRACT, которые позволяют извлечь содержимое из XML-документа. Если необходимо точно ввести данные вне операторов SQL. Использование типа данных XML гарантирует истинность значений XML, а не только произвольных текстовых строк. Для обеспечения совместимости с будущими, еще не установленными системами хранения, которые могут не поддерживать существующие типы, например CLOB (подробнее об этом см. в главе 2). Для получения преимуществ в будущих оптимизациях, которые будут поддерживать только XML-данные.Массивы
Массивы
Если вы хотите поместить в одно поле больше одного элемента, вместо типа ROW воспользуйтесь типом Array. Для этого примера в таблице CONTACTINFO объявим столбец Phone как массив, а затем создадим XML-схему, которая будет преобразовывать массив в XML:
Например:
CREATE TABLE CONTACTINFO ( | |
Name | CHARACTER (30) |
Phone | CHARACTER (13) ARRAY [4] |
) ; |
Теперь воспользуемся следующей XML-схемой для преобразования этого типа:
<xsd:complexType Name='ARRAY_4.CHAR_13'>
<xsd:annotation>
<xsd:appinfo>
<sqlxml:sqltype kind='ARRAY1
maxElements='4'
mappedElementType='CHAR_13'/>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element Name='element'
minOccurs='0' maxOccurs='4'
nillable='true' type='CHAR_13'/>
</xsd:sequence >
</xsd:complexType>
Результат будет примерно следующим:
<Phone>
<element>(888)555-llll</element>
<element>xsi:nil='true'/>
<element>(888)555-3434</element>
</Phone>
Элемент в массиве, содержащий xsi:nil='true', говорит о том, что второй телефонный номер в исходной таблице содержит неопределенное значение.
Мультимножества
Мультимножества
Номера телефонов из предыдущего примера могут также хорошо храниться и в мультимножествах. Для преобразования мультимножества воспользуемся следующим программным кодом:
CREATE TABLE CONTACTINFO ( | |
Name | CHARACTER (30) |
Phone | CHARACTER (13) MULTISET |
) ; |
Преобразуем этот тип в XML с помощью такой схемы:
<xsd:complexType Name='MULTISET.CHAR_13'>
<xsd:annotation>
<xsd:appinfo>
<sqlxml:sqltype kind='MULTISET'
mappedElementType='CHAR_13'/>
</xsd: appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element Name='element'
minOccurs='0' maxOccurs='unbounded'
nillable='true' type='CHAR_13'/>
</xsd:sequence >
</xsd:complexType>
Результат будет примерно следующим:
<Phone>
<element>(888)555-llll</element>
<element>xsi:nils' true'I>
<element>(888)555-3434</element>
</Phone>
Обработка неопределенных значений
Обработка неопределенных значений
Поскольку SQL-данные могут быть неопределенными значениями, необходимо решить, как представлять их в XML-документе. Неопределенные значения могут быть представлены либо как нуль, либо как отсутствие всякого значения. Если элемент столбца необходимо представить как неопределенное (нулевое) значение, то он будет иметь атрибут xsi:nil="true". Это может быть сделано следующим способом:
<row>
<FirstName>Bill</FirstName>
<LastName>Bailey</LastName>
<City xsi:nil="true" />
<AreaCode>714</AreaCode>
<Telephone>5 55-22 22</Telephone>
</row>
Если элемент столбца отсутствует, то выполните следующее:
<row>
<FirstName>Bill</FirstName>
<Las tName>Bailey</Las tName>
<AreaCode>714</AreaCode>
<Telephone>55 5-22 22</Telephone>
</row>
При выборе этой опции строка содержит неопределенное значение, которое
"отсутствует". С ним нет связей.
Оператор XMLAGG
Оператор XMLAGG
XMLAGG — это агрегирующая функция, которая создает единственный XML-документ из других XML-документов или их отдельных фрагментов. Агрегирование содержит дерево элементов. Рассмотрим это на примере:
SELECT XMLELEMENT
( NAME "City",
XMLATTRIBUTES ( с.City AS "name" ) ,
XMLLAGG (XMLELEMENT ( NAME "last" c.LastNa,e )
)
) AS "CityList"
FROM CUSTOMER С
GROUP BY City ;
При обработке таблицы CUSTOMER этот запрос выведет следующее:
<City name="Decatur">
<last>Bailey</last>
</City>
<City name= "Philo">
<last>Stetson</last>
<last>Stetson</last>
<last>Wood</last>
</City
<City name="Springfield">
<last>Abelson</last>
</City>
Оператор XMLCONCAT
Оператор XMLCONCAT
Оператор XMLCONCAT обеспечивает альтернативный способ создания дерева элементов. Это осуществляется путем связывания его XML-аргументов. Например:
SELECT с.LastName
XMLCONCAT (
XMLELEMENT ( NAME "first", c.FirstName,
XMLELEMENT ( NAME "last", c.LastName)
) AS "Result" FROM CUSTOMER с ;
В результате получится следующее:
LastName | Result |
Abelson |
<first>Abe</first>
<last>Abelson</last> |
Bailey | <first>Bill</first>
<last>Bailey</last> |
Оператор XMLELEMENT
Оператор XMLELEMENT
Оператор XMLELEMENT создает XML-элемент. Этот оператор может использоваться в операторе SELECT для помещения данных формата XML в базу данных SQL. Рассмотрим следующий пример:
SELECT с.LastName
XMLELEMENT ( NAME "City", c.City ) AS "Result"
FROM CUSTOMER С
WHERE LastName="Abelson" ;
Возвращаемый результат:
LastName | Result |
Abelson | <City>Springfield</City> |
Оператор XMLFOREST
Оператор XMLFOREST
Оператор XMLFOREST создает дерево (forest) элементов из списка аргументов. Каждый аргумент оператора создает новый элемент. Ниже приведен пример использования такого оператора.
SELECT с . LastNartie
XMLFOREST (с.City,
с.AreaCode,
с.Telephone ) AS "Result"
FROM CUSTOMER с
WHERE LastName="Abelson" OR LastName="Bailey" ;
В результате вы получите следующую информацию:
LastName | Result |
Abelson | <City>Springfield</City> <AreaCode>714</AreaCode> <Telephone>555-llll</ Telephone> |
Bailey | <City>Decatur</City> <AreaCode>714</AreaCode> <Telephone>555-llll</ Telephone> |
Оператор XMLGEN
Оператор XMLGEN
Первый аргумент оператора XMLGEN— это шаблон, который содержит символы-заполнители для значений, которые будут добавлены позже. Символы-заполнители представлены в форме "{$name}". Последовательность аргументов задает значения и связанные с ними имена, которые характеризуют шаблон. Ниже приведен пример использования этого оператора.
SELECT с.LastName
XMLGEN ( '<CUSTOMER Name="{$LASTNAME}">
<City>{$CITY}</City>
</CUSTOMERS ,
c.LastName AS Name,
с City ) AS "Result"
FROM CUSTOMER с
WHERE LastName="Abelson" OR LastName="Bailey" ;
Результат будет следующим:
LastName | Result |
Abelson | <CUSTOMER Name="Abelson"
<City>Springfield</City> </CUSTOMER> |
Bailey | <CUSTOMER Name="Bailey"
<City>Decatur</City> </CUSTOMER> |
Отдельные UDTтипы
Отдельные UDT-типы
С отдельными UDT-типами вы можете делать то же самое, что и с доменами, однако здесь необходим более строгий подход к определению типа. Например: CREATE TYPE WestCoast AS Character (2) FINAL ;
Для преобразования этого типа в XML-тип используется следующая XML-схема:
<xsd:simpleType>
Name='UDT.SalesWestCoast'>
<xsd:annotation>
<xsd:appinfo>
<sqlxml:sqltype kind='DISTINCT'
schemaName='Sales'
typeName='WestCoast'
mappedType='CHAR_2'
final='true'/>
<xsd:appinfo>
</xsd:annotation>
<xsd:restriction base='CHAR_2'/>
</xsd:simpleType>
В результате создается элемент, похожий на созданный для домена, описанного нами ранее.
Получение XML результатов при использовании операторов SQL
Получение XML результатов при использовании операторов SQL
SQL: 2003 имеет пять операторов, XMLELEMENT, XMLFOREST, XMLGEN, XMLCONCAT и XMLAGG, которые при применении к содержимому базы данных SQL дают XML-результат.
Преобразование данных из формата SQL в формат XML и наоборот
Преобразование данных из формата SQL в формат XML и наоборот
Для обмена данными между базами данных SQL и XML-документами различные элементы базы данных SQL должны быть преобразованы в эквивалентные элементы XML-документа и наоборот. Как вы узнаете в следующих разделах, порой преобразование просто необходимо для удачного выполнения некоторых операций.
Преобразование идентификаторов
Преобразование идентификаторов
В отличие от SQL, XML более точно подходит к определению идентификаторов. Прежде чем стать частью XML-документа, символы, допустимые в SQL и недопустимые в XML, должны быть соответствующим образом преобразованы. SQL поддерживает неограниченные идентификаторы. Это означает, что все виды добавочных символов, такие как %, $ и &, будут допустимыми до тех пор, пока они заключены в двойные кавычки. Но такие символы не допустимы для XML. Кроме того, имена в XML, начинающиеся с символов XML, в любых комбинациях уже зарезервированы и, таким образом, не могут использоваться без каких-либо негативных последствий. Именно поэтому идентификаторы SQL, начинающиеся с этих символов, должны быть изменены.
При преобразовании из SQL в XML все идентификаторы конвертируются в Unicode. Любые же идентификаторы языка SQL, которые являются также допустимыми именами XML, остаются неизменными. Символы идентификатора языка SQL, не допустимые для имен XML, заменяются шестнадцатеричным кодом. Полученный результат имеет форму записи типа "_хНННН_" или "_xНННННННН_", где Н— шестнадцатеричный разряд верхнего регистра. Например, символ подчеркивания "_" будет представлен как "_x005F_". Двоеточие— как "_х003А_". Эти представления являются кодами для описания в системе Unicode таких символов, как подчеркивание и двоеточие. В случае, если идентификатор SQL начинается с символов х, т или /, перед такими символами необходимо поставить префикс с кодом в форме "_xFFFF_".
Преобразовать символы из XML-формата в SQL-формат гораздо проще. Все, что для этого необходимо сделать, — это развернуть символы XML-имени в последовательность "_XFFFF_" или "_XFFFFFFFF_". Всякий раз, когда вы находите такую последовательность, заменяйте ее символами, соответствующими символам Unicode. Если же имя XML начинается с символов "_XFFFF_", игнорируйте их.
Следуя этим простым правилам, вы можете преобразовывать идентификатор SQL в XML-имя, а затем вернуться к идентификатору SQL. Однако это хорошее правило не действует для преобразования XML-имени в идентификатор SQL и наоборот.
Преобразование наборов символов
Преобразование наборов символов
В языке SQL поддержка наборов символов зависит от его реализации. Это означает, что приложение DB2 производства компании IBM может поддерживать наборы символов, которые не поддерживаются приложением SQL Server компании Microsoft. SQL Server, в свою очередь, поддерживает наборы символов, которые не поддерживаются приложением Oracle. Несмотря на то что большинство общих наборов символов практически всегда универсально поддерживается тем или иным приложением, использование мало распространенных символов может усложнить перемещение вашей базы данных и приложения с одной платформы реляционной СУБД (РСУБД) на другую.
У XML нет никаких проблем совместимости с наборами символов, поскольку он поддерживает только один набор — Unicode. Этот универсальный набор символов, публикуемый консорциумом Unicode Consortium, представляет собой стандартный набор символов для компьютеров, в котором каждому письменному знаку на любом языке присвоен определенный номер. С точки зрения обмена данными между любыми реализациями языка SQL и XML это очень хорошо. Поставщики РСУБД должны описать преобразование строк из каждого набора символов в символы Unicode и обратное преобразование символов Unicode в строки, состоящие из наборов символов. К счастью, XML не поддерживает множество наборов символов, что освобождает поставщиков от большого количества проблем, связанных с бесчисленными преобразованиями символов.
Преобразование не предопределенных типов данных в XML
Преобразование не предопределенных типов данных в XML
В SQL:2003 к не предопределенным типам данных относятся домены, отдельные UDT-типы, строки, массивы и мультимножества. Для преобразования каждого из этих XML-типов данных используется соответствующий XML-код. Примеры преобразования таких типов данных рассматриваются в следующих разделах.
Преобразование таблиц
Преобразование таблиц
Вы можете преобразовать таблицу в XML-документ, а также все таблицы в схему или все таблицы в каталог. Преобразование также определяет привилегии. Пользователь, имеющий привилегию SELECT только для нескольких столбцов таблицы, может преобразовать в XML-документ только эти столбцы. В действительности преобразование порождает два документа: один, который содержит данные в таблице, а другой — XML-схему, описывающую первый документ. Ниже приведен пример преобразования SQL-таблицы в документ, содержащий XML-данные.
<CUSTOMER>
<row>
<FirstName>Abe</FirstName>
<LastName>Abelson</LastName>
<City>Springfield</City>
<AreaCode>714</AreaCode>
<Telephone>555-llll</Telephone>
</row>
<row>
<FirstName>Bill</FirstName>
<LastName>Bailey</LastName>
<City>Decatur</City>
<AreaCode>714</AreaCode>
<Telephone>555-2222</Telephone>
</row>
.
.
.
</CUSTOMER>
Основной элемент документа дал имя таблице (CUSTOMER). Каждая строка таблицы содержится в пределах элемента <row> (в данном примере таких строк две). Кроме того, каждая строка таблицы содержит последовательность элементов столбца (атрибутов), каждый из которых получает имя после связывания со столбцом в исходной таблице (столбцы FirstName, LastName, City, AreaCode, Telephone). Каждый элемент столбца содержит значение данных.
Преобразование типов данных
Преобразование типов данных
В SQL:2003 определено, что данные типа SQL преобразуются в наиболее близкую схему XML-данных. Формулировка "наиболее близкая" означает, что все значения, допустимые для SQL-типа, будут допустимы и для типа XML-схемы, а наименее возможные значения, не допустимые для SQL-типа, будут допустимы для типа XML-схемы. Элементы XML, такие как maxlnclusive и minlnclusive, могут ограничивать значения, допускаемые типом XML-схемы, до значений, допускаемых соответствующим SQL-типом. Например, если тип SQL-данных Ограничивает значения типа INTEGER в диапазоне значений от -2157483648 до 2157483647, в XML значение minlnclusive может быть задано числом -2157483648. Ниже приведен пример такого преобразования.
<xsd:simpleType>
<xsd:restriction base="xsd:integer">
<xsd:maxlnclusive value="2157483647"/>
<xsd:minlnclusive value="-21574 83648"/>
<xsd:annotation>
<sqlxml:sqltype name="INTEGER"/>
</xsd:annotation>
</xsd:restriction>
</xsd:simpleType>
Раздел примечаний содержит информацию из описания SQL-типа, который в настоящий момент не используется XML, но позднее, при преобразовании этого документа в SQL-формат, может быть очень кстати.
Создание XMLсхемы
Создание XML-схемы
При преобразовании данных из SQL в XML первый созданный документ содержит данные, а второй — информацию о схеме. В качестве примера рассмотрим схему для документа CUSTOMER (см. "Преобразование таблиц").
<xsd:schema>
<xsd:simpleType name="CHAR_15">
<xsd:restriction base="xsd:string">
<xsd:lenght value = "15"/>
</xsd;restriction>
</xsd:simpleType>
<xsd:simpleType name="CHAR_25">
<xsd:restriction base="xsd:string">
<xsd:lenght value = "25"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="CHAR_3">
<xsd:restriction base="xsd:string">
<xsd:lenght value = "3"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name-"CHAR_8">
<xsd:restriction base="xsd:string">
<xsd:lenght value = "8"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:sequence>
<xsd:element name="FirstName" type="CHAR_15"/>
<xsd:element name="LastName" type="CHAR_25"/>
<xsd:element
name="City" type="CHAR_25" nillable="true"/>
<xsd:element
name="AreaCode" type="CHAR_3" nillable="true"/>
<xsd:element
name="Telephon" type="CHAR_8" nillable="true"/>
<xsd:sequence>
</xsd:schema>
Эта схема подходит в том случае, если при обработке неопределенных значений используется опция "нуль". Опция "отсутствие" требует несколько иного определения элемента. Например:
<xsd:element
name="City" type="CHAR_25 minOccurs="0"/>
Строки
Строки
Тип ROW позволяет поместить целую строку с ценной информацией в одно лишь отдельное поле строки таблицы. Тип ROW создается как часть описания таблицы следующим образом:
CREATE TABLE CONTACTINFO ( | |
Name | CHARACTER (30) |
Phone | ROW (Home CHAR (13), Work CHAR (13)) |
Теперь воспользуемся следующей XML-схемой для преобразования этого типа:
<xsd:complexType Name='ROW.1'>
<xsd:annotation>
<xsd:appinfo>
<sqlxml:sqltype kind='ROW'
<sqlxml:field name='Home'
mappedType='CHAR_13'/>
<sqlxml:field name='Work'
mappedType='CHAR_13'/>
</sqlxml:sqltype>
<xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element Name='Home' nillable='true'
Type='CHAR_13'/>
<xsd:element Name='Work' nillable='true'
Type='CHAR_13'/>
</xsd:sequence>
</xsd:complexType>
Такое преобразование создает для столбца следующий XML-тип:
<Phone>
<Home>(888)555-llll</Home>
<Work>(888)555-1212</Work>
</Phone>
Тип данных XML
Тип данных XML
В SQL:2OO3 впервые был представлен новый для SQL тип данных — тип XML. Это означает, что согласованные между собой реализации могут хранить и работать непосредственно с данными формата XML, без их предварительного преобразования из какого-либо типа данных SQL в тип XML.
Несмотря на то что XML-данные встроены в любую поддерживающую их реализацию, они работают как тип данных, определяемый пользователем (UDT-тип, user-defined type). XML-данные обеспечивают непосредственное взаимодействие языков SQL и XML, поскольку позволяют приложениям выполнять SQL-операции над содержимым XML и, наоборот, XML-операции над содержимым SQL. Вы можете использовать столбцы с XML-данными совместно со столбцами, содержащими любые предопределенные типы данных (см. главу 2), объединяя их в запросах с предложением WHERE. А ваша СУБД, в свою очередь, следуя истинным традициям реляционных баз данных, будет определять оптимальный путь для выполнения запроса, что в конце концов и произойдет.