 | Уровень сложности: средний Иоана Урсу, Программист-консультант, IBM Silicon Valley Lab Эйлин Лин, Старший технический специалист, IBM Silicon Valley Lab Аакаш Бордиа, Штатный инженер-программист,
IBM
Себастьян Ханель, Программист-стажер,
IBM
24.05.2007
Поддержка pureXML™, реализованная в WebSphere® Federation Server Version 9.1, позволяет объединять локальные и удаленные данные, хранящиеся в формате XML. Также вы можете создавать в своих новых приложениях запросы данных XML с помощью языков SQL/XML и XQuery. Узнайте, как эффективно использовать эту мощную комбинацию!
Введение
IBM WebSphere Federation Server предоставляет виртуализованный доступ к разрозненным источникам данных в реальном времени. Это позволяет создавать новые проекты со значительно меньшим временем выхода на рынок, дополнять хранилище данных специализированными запросами, а также формировать унифицированное представление данных вашего предприятия.
Благодаря поддержке pureXML, реализованной в DB2® 9, WebSphere Federation Server Version 9.1 предоставляет возможность интеграции реляционных данных и данных XML в единой базе данных. Теперь пользователи Federation могут интегрировать в объединенную базу данных данные XML в исходном формате. Хотя на сегодняшний день еще не реализована прямая поддержка удаленных типов данных XML, пользователи Federation могут интегрировать удаленные данные XML с помощью представлений XML.
В этой статье показано, как интегрировать данные XML, хранящиеся локально и удаленно, с помощью WebSphere Federation Server Version 9.1. На примере книжного магазина мы рассмотрим, как можно использовать расширенные возможности языков XQuery и SQL/XML для управления хранящимися локально данными XML. После этого мы обсудим, какие действия необходимо предпринять для интеграции данных XML, хранящихся удаленно, а также связанные с этим вопросы. Расширив пример книжного магазина до распределенной книготорговой сети, мы покажем, как задать конфигурацию различных источников данных. На нескольких примерах запросов мы покажем, как использовать языки SQL/XML и XQuery для составления запросов к таким системам. В заключении мы расскажем, над чем мы сейчас работаем, чтобы еще больше упростить использование этих функций.
Интеграция локальных данных XML
В качестве основных языков запросов в DB2 поддерживаются SQL и XQuery. Оба языка работают с соответствующими моделями данных и могут использоваться независимо друг от друга. Однако интеграция двух языков, поддерживаемых DB2, позволяет существенно расширить возможности приложений баз данных. Поскольку многие приложения работают одновременно с существующими реляционными данными и XML, возникает необходимость комбинировать и коррелировать эти типы данных в запросах. Для поддержки такой интеграции в DB2 9 реализованы следующие функции:
- Функции и предикаты SQL/XML, которые позволяют приложениям работать с данными XML в SQL
- Такие функции как
db2-fn:sqlquery
, которые позволяют приложениям использовать в XQuery реляционные данные
Поскольку DB2 с помощью объединения способна предоставлять прозрачный доступ к разнородным реляционным данным, для указания реляционных таблиц в SQL/XML и XQuery можно использовать псевдонимы.
В этом разделе мы обсудим построение запросов к локальным полям XML в сочетании с псевдонимами с помощью SQL/XML и XQuery. В ходе этого обсуждения мы будем рассматривать сценарий, описанный на рисунке 1:
Рисунок 1. Сценарий книжного магазина
Конфигурация сценария представлена на рисунке 2:
Рисунок 2. Конфигурация сценария книжного магазина
Создание запроса к локальным данным XML и псевдонимам в SQL
DB2 поддерживает извлечение данных XML и создание запросов к данным XML в запросах SQL с помощью новых функций и предикатов SQL/XML, в числе которых XMLQUERY, XMLEXISTS и
XMLTABLE.
Начнем с этого небольшого примера. Приведенный ниже запрос извлекает информацию о книге, ее остатках на складе и городе, в котором расположен склад, для книги, код ISBN которой заканчивается на "69":
SELECT b.xmlinfo, i.quantity, w.city
FROM bookstore b, inventory i, warehouse w
WHERE b.isbn = i.isbn
AND i.warehouse id = w.warehouse id
AND b.isbn LIKE '%69'
|
В приведенном выше примере мы объединяем два псевдонима и локальную таблицу, содержащую поле XML.
Вывод этого запроса (показан в виде prettyPrint) может выглядеть следующим образом:
<book isbn="0201633469" year="1993" category="Computers">
<title>TCP/IP Illustrated</title>
<author><last>Stevens</last><first>W. Richard</first></author>
<publisher>Addison-Wesley Professional</publisher>
<price>65.00</price>
</book>,
3,
'San Francisco'
|
В следующем примере используется функция XMLTABLE для получения таблицы из локального поля XML, после чего результирующая таблица используется для добавления данных в псевдоним. Это делается для того, чтобы хранить авторов книг в отдельной таблице, извлекая данные из документов XML в таблицу книжного магазина.
INSERT INTO author
SELECT xb.*
FROM bookstore b, XMLTABLE(
'$doc/book' PASSING b.xmlinfo AS "doc" COLUMNS
"ISBN" CHAR(10) PATH '@isbn',
"LASTNAME" VARCHAR(30) PATH 'author/last',
"FIRSTNAME" VARCHAR(30) PATH 'author/first'
) AS xb;
|
В следующем примере возвращаются полные документы книжного магазина, для дополнительной фильтрации используется XMLEXISTS. Запрос вернет только записи книг, стоимость которых ниже 65,50 долларов США и которые есть в наличии на складе. Предложение passing by задает связь между контекстом XQuery и SQL.
SELECT b.isbn, i.warehouse id, i.quantity
FROM bookstore b, inventory i
WHERE i.isbn = b.isbn
AND i.quantity > 0
AND XMLEXISTS('$doc/book[price < 65.50]'
PASSING BY REF b.xmlinfo AS "doc")
|
В следующем примере функция XMLQUERY применяется в предложении WHERE, чтобы извлекать значение из локального поля XML и использовать его для объединения с полями псевдонима. Здесь мы определяем, сколько книг опубликовал автор каждой книги, в названии которой содержится ключевое слово "TCP/IP":
SELECT DISTINCT count(*) as NUMBER OF BOOKS, a.firstname, a.lastname
FROM author a, bookstore b
WHERE XMLSERIALIZE(CONTENT XMLQUERY('$doc/book/author/first/text()'
PASSING BY REF b.xmlinfo AS "doc"
RETURNING SEQUENCE) AS CHAR(50)) = a.firstname
AND XMLSERIALIZE(CONTENT XMLQUERY('$doc/book/author/last/text()'
PASSING BY REF b.xmlinfo AS "doc"
RETURNING SEQUENCE) AS CHAR(50)) = a.lastname
AND XMLSERIALIZE(CONTENT XMLQUERY('$doc/book/title/text()'
PASSING BY REF b.xmlinfo AS "doc"
RETURNING SEQUENCE) AS CHAR(50)) like '%TCP/IP%'
GROUP BY a.firstname, a.lastname, b.isbn
|
Создание запроса к локальным данным XML и псевдонимам в XQuery
DB2 9 позволяет осуществлять извлечение реляционных данных и доступ к ним с помощью XQuery. Решение этой задачи облегчают функции конструктора SQL/XML, которые преобразуют реляционные данные в формат XML и создают одно поле типа XML, которое может служить входной информацией для XQuery. Пользователи могут использовать любые существующие реляционные данные для отбора документов XML в рамках обработки XQuery. Функцию db2-fn:sqlquery
можно использовать не только для ограничения входных данных XQuery, но и для их расширения.
В приведенном ниже примере запрос XQuery создает документ, содержащий информацию о конкретной книге и ее запасах на складе. Информация о книге представлена в виде документа XML, полученного из поля XML XMLINFO.
Информация о складских запасах получается из объединения двух реляционных псевдонимов. Запрос SQL/XML создает элемент XML warehouse с пятью дочерними элементами (warehouse ID, street, city, state и quantity), значения которых берутся из объединения двух псевдонимов WAREHOUSE и INVENTORY. В результате мы получаем отчет по складским запасам книги, дополненный информацией о складах.
XQUERY
let $b := db2-fn:sqlquery("
SELECT xmlinfo
FROM bookstore
WHERE isbn='0201633469'")
let $w := db2-fn:sqlquery("
SELECT XMLELEMENT(NAME warehouse, XMLFOREST(
w.warehouse id, w.street, w.city, w.state, i.quantity))
FROM warehouse w, inventory i
WHERE w.warehouse id = i.warehouse id
AND i.isbn = '0201633469'")
return
<report>
{$b}
<stock>{$w}</stock>
</report>
|
Вывод этого запроса (показан в виде prettyPrint) может выглядеть следующим образом:
<report>
<book isbn="0201633469" year="1993" category="Computers">
<title>TCP/IP Illustrated</title>
<author><last>Stevens</last><first>W. Richard</first></author>
<publisher>Addison-Wesley Professional</publisher>
<price>65.00</price>
</book>
<stock>
<WAREHOUSE>
<WAREHOUSE ID>1</WAREHOUSE ID>
<STREET>1234 Market Street</STREET>
<CITY>San Francisco</CITY>
<STATE>CA</STATE>
<QUANTITY>3</QUANTITY>
</WAREHOUSE>
<WAREHOUSE>
<WAREHOUSE ID>2</WAREHOUSE ID>
<STREET>4012 1st Street</STREET>
<CITY>San Jose</CITY>
<STATE>CA</STATE>
<QUANTITY>1</QUANTITY>
</WAREHOUSE>
</stock>
</report>
|
В следующем примере производится фильтрация входных документов XQuery путем объединения с псевдонимом. Мы запрашиваем названия книг, стоимость которых меньше 65 долларов США, хранящихся на складе с ID равным 1.
XQUERY
for $e in db2-fn:sqlquery("
SELECT b.xmlinfo
FROM bookstore b, inventory i
WHERE b.isbn = i.isbn
AND i.warehouse id = 1")/book
where $e/price > 65.00
return $e/title
|
Вывод этого запроса (показан в виде prettyPrint) может выглядеть следующим образом:
<title>Advanced Programming in the UNIX environment</title>
|
Эти примеры показывают мощь интеграции XQuery и SQL – а именно, возможность совместного использования реляционных данных, доступ к которым производится по псевдониму, и данных, хранящихся в XML.
Интеграция удаленных данных XML
В WebSphere Federation Server Version 9.1 нельзя создать псевдоним для удаленной таблицы или представления, содержащих поле типа XML. Для интеграции данных XML из различных реляционных баз данных можно использовать представления сериализованных строковых данных XML, реализовав таким образом механизм соответствия удаленных и локальных данных XML.
Этапы такого подхода представлены на рисунке 3:
- Сериализация данных XML на удаленной базе данных с помощью представления
- Создание псевдонима на основе этого представления
- Преобразование данных XML из локального псевдонима в локальное представление на федеративном сервере
Рисунок 3. Графическое представление процесса интеграции удаленных данных XML
Предположим, у нас есть удаленная таблица Oracle со следующим определением:
CREATE TABLE bookstore(isbn CHAR(10), xmlinfo XMLType);
|
Далее мы сериализуем данные XML в следующее представление на удаленном сервере:
CREATE VIEW bookstore blob (isbn, xmlinfo) AS
SELECT b.isbn, b.xmlinfo.getBlobVal(nls charset id('utf8'))
FROM bookstore b;
|
У данных XML нет определенной длины. Поскольку предполагается возможность добавления больших документов, тип внешних данных XML будет обрабатываться аналогично данным LOB. Однако для документов меньшего размера можно указать другой, более подходящий тип данных, например VARCHAR, который позволит достичь большей производительности, чем большие символьные объекты (CLOB).
После сериализации удаленных данных XML можно создать псевдоним удаленного представления на федеративном сервере следующим образом:
CREATE NICKNAME bookstore blob FOR server name.myuser.bookstore blob;
|
Далее необходимо преобразовать строку на федеративном сервере обратно в тип XML. Используем функцию
XMLPARSE
, которая преобразует сериализованную строку в значение XML, как показано в следующем предложении:
CREATE VIEW vbookstore (isbn, xmlinfo) AS
SELECT isbn, XMLPARSE(DOCUMENT xmlinfo PRESERVE WHITESPACE)
FROM bookstore blob;
|
Теперь вы можете манипулировать удаленными данными XML с помощью функций XQuery и SQL/XML точно так же, как и локальными данными XML.
Проверка удаленных данных XML
На вход парсера DB2 должны подаваться только верные данные XML. Если поданные данные не могут быть обработаны, будет возвращена ошибка. Например, вы можете создать псевдоним для удаленного представления, которое извлекает часть документа XML или значение определенного элемента. Приведенное ниже представление Oracle будет извлекать содержимое элемента XML:
CREATE VIEW bookstore blob (isbn, xmlinfo) AS
SELECT extract(xmlinfo, '//book').getBlobVal(nls charset id('utf8'))
FROM bookstore;
|
В результате будет возвращена последовательность узлов в виде экземпляра типа XML. Если к выходу псевдонима, созданного для вышеприведенного удаленного представления, применить функцию XMLPARSE, парсер DB2 может выдать сообщение об ошибке, связанной с неверной структурой документа XML (SQL16132N).
Это будет считаться ошибкой, вызванной неправильным использованием.
Одним из способов устранения такой ошибки является добавление элемента root как части определения представления. Например, вы можете определить на источнике данных Oracle следующее представление:
CREATE VIEW bookstore blob (isbn, xmlinfo) AS
SELECT '<root>' ||
extract(xmlinfo,//book').getBlobVal(nls charset id('utf8'))||
'</root>'
FROM bookstore;
|
Также можно использовать на федеративном сервере проверку с помощью схемы в сочетании с XMLPARSE:
CREATE VIEW vbookstore (isbn, xmlinfo) AS
SELECT isbn, XMLVALIDATE(XMLPARSE(DOCUMENT xmlinfo WHITESPACE)
ACCORDING TO XMLSCHEMA ID bookschema)
FROM bookstore blob;
|
bookschema является локальным зарегистрированным объектом схемы DB2, который может представлять схему XML удаленного источника данных. Для регистрации схемы книжного магазина в DB2 можно использовать команду
REGISTER XMLSCHEMA
, что продемонстрировано в следующем примере:
REGISTER XMLSCHEMA schema URI FROM content URI AS bookschema COMPLETE;
|
По умолчанию XMLPARSE проверяет только правильность оформления данных, без проверки по схеме.
Функция
XMLVALIDATE
проверяет заданное значение XML на соответствие заданной схеме XML или схеме, полученной из указания схемы в документе.
Необходимо помнить о следующих ограничениях:
-
Если
XMLVALIDATE
вызывается без указания схемы, будет использована либо внутренняя схема, либо, при ее отсутствии, DTD. Если парсер не сможет получить доступ к местонахождению внешней схеме или DTD, он вернет сообщение об ошибке.
-
Если вызов
XMLVALIDATE производится по зарегистрированной схеме или указанному URI, будет выполнена проверка по этой схеме. Если указана внешняя схема, она имеет преимущество над указанием внутренней схемы. В федеративных запросах этот механизм будет переопределять внутреннюю схему документа в случае, если информация о схеме недоступна серверу DB2.
Вопросы кодирования удаленных данных XML
При сериализации данных XML тип используемой кодировки определяется целевым типом. В выходных данных XML будет содержаться информация о внутренней кодировке. Однако в выходных данных, отличных от XML, может отсутствовать объявление XML, в этом случае выбор кодировки выполняется парсером XML DB2 или федеративным сервером.
В общем случае, если данные XML отправляются и получаются как данные формата XML, то вопросов преобразования кодировки не возникает. Однако при хранении сериализованных данных XML в символьных типах SQL могут возникнуть проблемы, связанные с преобразованием кодовых страниц.
При работе с сериализованными удаленными данными XML в федеративных запросах могут возникнуть следующие проблемы, связанные с кодировкой:
Удаленные данные XML сериализуются в на двоичные данные:
При передаче данных с удаленного клиента на федеративный сервер потери данных не произойдет.
Будут применены правила кодировки парсера XML DB2. Кроме того, если указана внутренняя кодировка, не являющаяся допустимой схемой кодировки IBM, парсер выдаст сообщение об ошибке
SQL16168N
. В таких случаях мы рекомендуем исключить объявление XML из сериализованных удаленных строковых данных. Например, в Oracle можно использовать следующее определение удаленного представления, в котором не будет объявления XML. Oracle добавляет объявление XML по умолчанию, если оно присутствует в документе XML.
CREATE VIEW bookstore blob (isbn, xmlinfo) AS
SELECT isbn,
extract(xmlinfo,'/').getBlobVal(nls charset id('utf8'))
FROM bookstore; |
Удаленные данные XML сериализуются в символьные данные:
-
В качестве кодовой страницы данных XML будет использоваться кодовая страница федеративной базы данных (Unicode). При передаче данных с удаленного клиента на федеративный сервер возможна потеря данных. В случае, если преобразование привело к замене символов, в зависимости от поведения источника данных и реализации сервера может быть выдано предупреждение.
-
Будут действовать правила кодировки парсера XML DB2. Если внутренняя кодировка указана и не является допустимой схемой кодировки IBM, парсер выдаст сообщение об ошибке SQL16168N. В таких случаях мы рекомендуем исключить объявление XML, если сериализация позволяет сделать это. Например, в Oracle можно использовать следующее определение удаленного представления, исключающее объявление XML:
CREATE VIEW clob books (isbn, xmlinfo) AS
SELECT isbn, extract(xmlinfo, '/').getClobVal()
FROM bookstore; |
Чтобы исключить проблемы, связанные с преобразованиями кодировки, вместо символьных типов рекомендуется использовать типы
FOR BIT DATA или BLOB. В федеративных системах необходимо учитывать, что различные источники данных XML могут иметь разную внутреннюю кодировку. В таких случаях рекомендуется исключать объявление XML, если сериализация позволяет сделать это.
Сценарий распределенной книготорговой сети
Основываясь на сценарии, представленном в разделе Интеграция локальных данных XML, рассмотрим схему взаимоотношений объектов, описывающую сценарий онлайнового книжного магазина, которая представлена на Рисунке 4. Обратите внимание, что таблица BOOKSTORE расположена и на федеративном сервере, и в базе данных Oracle 10g Release 2.
Рисунок 4. Сценарий распределенной книготорговой сети
Процесс создания серверов, надстроек и соответствия пользователей описан в Приложении A3. Результирующая конфигурация представлена на рисунке 5:
Рисунок 5. Конфигурация сценария книжного магазина
Сериализация удаленных данных XML в удаленные представления
На сервере Oracle 10gR2 имеется одна таблица BOOKSTORE. Данные XML сериализуются в данные типа BLOB с помощью следующего удаленного представления:
CREATE VIEW bookstore blob (isbn, xmlinfo) AS
SELECT b.isbn, b.xmlinfo.getBlobVal(nls charset id('utf8'))
FROM bookstore2 b;
|
Таблица REVIEW размещается на сервере SQL Server 2005. Данные XML сериализуются в BLOB с помощью следующего удаленного представления:
CREATE VIEW review blob (review id, xmlinfo) AS
SELECT review id, CAST(xmlinfo AS VARBINARY(MAX))
FROM review;
|
Таблица CUSTOMER INFO хранится в базе данных DB2 9, и ее данные XML сериализуются в поле BLOB с помощью следующего удаленного представления:
CREATE VIEW customer info blob (customer id, xmlinfo) AS
SELECT customer id, XMLSERIALIZE(xmlinfo AS BLOB INCLUDING XMLDECLARATION)
FROM customer info;
|
Создание псевдонимов и локальных представлений XML
В приведенных ниже предложениях определяются реляционные псевдонимы для нашего примера:
CREATE NICKNAME bookstore blob FOR "oracle10g2".myuser.bookstore blob;
CREATE NICKNAME review blob FOR "mssql".myuser.review vlob;
CREATE NICKNAME customer info blob
FOR "db2v91".myuser.customer info blob;
CREATE NICKNAME inventory FOR "db2v91".myuser.inventory;
CREATE NICKNAME warehouse FOR "db2v91".myuser.warehouse;
|
Поскольку в заказе, хранящемся в документе XML orders.xml, содержится перечень позиций, он представляется с помощью двух псевдонимов:
CREATE NICKNAME order (
order id CHAR(10) OPTIONS (XPATH '@id'),
order date DATE OPTIONS (XPATH '@date'),
customer id CHAR(10) OPTIONS (XPATH '@cid'))
FOR SERVER "xml server"
OPTIONS (
FILE PATH '/my/path/orders.xml',
XPATH '/orders/order');
CREATE NICKNAME order item (
order id VARCHAR(10) OPTIONS (XPATH '../@id'),
isbn CHAR(10) OPTIONS (XPATH '@isbn'))
FOR SERVER "xml server"
OPTIONS (
FILE PATH '/my/path/orders.xml',
XPATH '/orders/order/item');
|
Давайте теперь создадим локальные представления XML на основе этих реляционных псевдонимов:
CREATE VIEW vbookstore2 (isbn, xmlinfo) AS
SELECT isbn, XMLPARSE(DOCUMENT xmlinfo PRESERVE WHITESPACE)
FROM bookstore blob;
CREATE VIEW vreview (review id, xmlinfo) AS
SELECT review id, XMLPARSE(DOCUMENT xmlinfo PRESERVE WHITESPACE)
FROM review blob;
CREATE VIEW vcustomer info (customer id, xmlinfo) AS
SELECT customer id, XMLPARSE(DOCUMENT xmlinfo PRESERVE WHITESPACE)
FROM customer info blob;
|
Чтобы создать модель распределенного книжного магазина, определим представление UNION ALL на основе таблицы bookstore1 и представления vbookstore2:
CREATE VIEW big bookstore (isbn, xmlinfo) AS
SELECT isbn, xmlinfo FROM bookstore1
UNION ALL
SELECT isbn, xmlinfo FROM vbookstore2;
|
Создание запросов с помощью SQL/XML и XQuery
Пользователи могут задавать поддерживаемые запросы SQL/XML или XQuery к локальным представлениям, которые мы только что создали, не зная при этом, где расположены данные XML.
Для начала найдем обзоры каждой из книг с помощью функций публикации SQL/XML и функции
XMLTABLE
:
SELECT XMLELEMENT(NAME "book",
XMLFOREST(
b."title" AS "title",
r."review" AS "review"))
FROM big bookstore vb, vreview vr,
XMLTABLE('$doc/book' PASSING vb.xmlinfo AS "doc"
COLUMNS "isbn" CHAR(10) PATH '@isbn',
"title" VARCHAR(50) PATH 'title') as b,
XMLTABLE('$doc/reviews/review' PASSING vr.xmlinfo AS "doc"
COLUMNS "isbn" CHAR(10) PATH '@isbn',
"review" VARCHAR(70) PATH '.') as r
WHERE b."isbn" = r."isbn";
|
Пример вывода (в виде prettyPrint):
<book>
<title>Advanced Programming in the UNIX environment</title>
<review>A clear and detailed discussion of UNIX programming.</review>
</book>
<book>
<title>TCP/IP Illustrated</title>
<review>One of the best books on TCP/IP.</review>
</book> |
После этого можно использовать функции публикации SQL/XML в сочетании с другими конструкциями XML для создания перечня книг, проданных в различных местах. Ниже приведен форматированный вывод:
<list>
<state name="CA">
<city name="San Francisco">
<book>TCP/IP Illustrated</book>
</city>
<city name="San Jose">
<book>Advanced Programming in the UNIX environment</book>
<book>TCP/IP Illustrated</book>
<book>TCP/IP Illustrated</book>
</city>
</state>
<state name="NY">
<city name="New York">
<book>TCP/IP Illustrated</book>
</city>
</state>
</list>
|
Следующий запрос возвращает приведенный выше вывод (в последовательной форме):
VALUES (XMLELEMENT(NAME "list", (
SELECT XMLAGG (s.state)
FROM ( SELECT XMLELEMENT(NAME "state",
XMLATTRIBUTES(c.state AS "name"),
XMLAGG(c.city)) AS state
FROM ( SELECT ci."state" AS state,
XMLELEMENT(NAME "city",
XMLATTRIBUTES(ci."city" AS "name"),
XMLAGG(XMLELEMENT(NAME "book", b."title"))) AS city
FROM order o, order item oi,
big bookstore vb, vcustomer info vci,
XMLTABLE('$p/customer' PASSING vci.xmlinfo AS "p"
COLUMNS "id" VARCHAR(10) PATH '@id',
"city" VARCHAR(20) PATH 'address/city',
"state" VARCHAR(10) PATH 'address/state') AS ci,
XMLTABLE('$p/book' PASSING vb.xmlinfo AS "p"
COLUMNS "isbn" VARCHAR(10) PATH '@isbn',
"year" VARCHAR(4) PATH '@year',
"title" VARCHAR(100) PATH 'title') AS b
WHERE o.order id = oi.order id
AND oi.isbn = b."isbn"
AND o.customer id = ci."id"
AND o.order date <= '10/25/2004'
GROUP BY ci."city", ci."state") AS c
GROUP BY c.state) AS s
)));
|
Пользователь также может с помощью запроса XQuery получить список книг по компьютерной тематике, имеющих наилучшие оценки и цену ниже средней:
XQUERY
let $a := fn:avg(
db2-fn:xmlcolumn("BIG BOOKSTORE.XMLINFO")
/book[@category = "Computers"]/price/text())
for $book in db2-fn:xmlcolumn('BIG BOOKSTORE.XMLINFO')/book
for $review in db2-fn:xmlcolumn('VREVIEW.XMLINFO')/reviews/review
where
$book/@isbn = $review/@isbn
and $book/price/text() <= $a
and fn:contains($review/text(), "best")
return
<book>{$book/title/text()}</book> |
Пример вывода:
<book>TCP/IP Illustrated</book> |
Последний пример иллюстрирует использование SQL внутри XQuery и вложение конструкции XQuery. Этот запрос возвращает запасы каждой из книг на каждом из складов, а также суммарные запасы по каждой книге:
XQUERY
for $total order in db2-fn:sqlquery('
SELECT
XMLELEMENT(NAME "total order",
XMLFOREST(
i.isbn AS "isbn",
sum(i.quantity) AS "total"
)
)
FROM warehouse w, inventory i
WHERE w.warehouse id = i.warehouse id
GROUP BY i.isbn
')
let $warehouses := db2-fn:sqlquery('
SELECT
XMLAGG(
XMLELEMENT(NAME "warehouse",
XMLFOREST(
i.isbn AS "isbn",
i.quantity AS "quantity",
w.city AS "city",
w.warehouse id AS "id"
)
)
)
FROM warehouse w, inventory i
WHERE w.warehouse id = i.warehouse id
')[isbn=$total order/isbn]
return
<book isbn="{$total order/isbn}">
<stock total="{$total order/total}">
{
for $wh in $warehouses
return
<warehouse id="{$wh/id}">
<city>{$wh/city/text()}</city>
<quantity>{$wh/quantity/text()}</quantity>
</warehouse>
}
</stock>
</book>
|
В нашем примере вывод может иметь следующий формат:
<book isbn="0201563177">
<stock total="7">
<warehouse id="1">
<city>San Francisco</city>
<quantity>2</quantity>
</warehouse>
<warehouse id="2">
<city>San Jose</city>
<quantity>5</quantity>
</warehouse>
</stock>
</book>
<book isbn="0201633469">
<stock total="4">
<warehouse id="1">
<city>San Francisco</city>
<quantity>3</quantity>
</warehouse>
<warehouse id="2">
<city>San Jose</city>
<quantity>1</quantity>
</warehouse>
</stock>
</book>
|
Заключение
В этой статье показано, как можно использовать WebSphere Federation Server Version 9.1 для интеграции локальных и удаленных данных XML. Хотя пока невозможно определить псевдонимы для доступа к удаленным данным, эту задачу можно решить с помощью представлений.
В настоящее время мы работаем над реализацией федеративного доступа к удаленным данным XML. Эта работа не только исключит необходимость дополнительных настроек, описанных в этой статье, но и позволит повысить производительность, поскольку будет работать не с представлениями, а напрямую с данными. Более того, такой федеративный доступ позволит вносить изменения в удаленные данные XML. Мы уверены, что объединение и поддержка pureXML станут великолепным инструментом для вашего постоянно развивающегося предприятия.
Приложение: Сценарии конфигурирования
A1. Заполнение примера книжного магазина
При условии, что таблицы были созданы так, как было описано в разделе Интеграция локальных данных XML, вы можете заполнить их данными. Приведенные ниже строки показывают содержимое таблицы BOOKSTORE:
('0201633469',
<book isbn="0201633469" year="1993" category="Computers">
<title>TCP/IP Illustrated</title>
<author>
<last>Stevens</last>
<first>W. Richard</first>
</author>
<publisher>Addison-Wesley Professional</publisher>
<price>65.00</price>
</book>)
,
('0201563177',
<book isbn="0201563177" year="1992" category="Computers">
<title>Advanced Programming in the UNIX environment</title>
<author>
<last>Stevens</last>
<first>W. Richard</first>
</author>
<publisher>Addison-Wesley Professional</publisher>
<price>65.95</price>
</book>)
|
Предположим, что в таблице INVENTORY хранятся следующие данные:
SELECT * FROM inventory;
INVENTORY ID WAREHOUSE ID ISBN QUANTITY
------------ ------------ ---------- -----------
1001 1 0201633469 3
1002 1 0201563177 2
1003 2 0201633469 1
1004 2 0201563177 5
4 record(s) selected.
|
В таблице WAREHOUSE содержатся следующие данные:
SELECT * FROM warehouse;
WAREHOUSE ID STREET CITY STATE
------------ ------------------ ------------- -----------------
2 4012 1st Street San Jose CA
1 1234 Market Street San Francisco CA
2 record(s) selected.
|
Предполагается, что таблица AUTHOR пуста.
A2. Создание таблиц для сценария распределенной книготорговой сети
Документы XML, определяющие отношение BOOKSTORE, хранятся в двух таблицах. Первая - это локальная таблица BOOKSTORE, находящаяся на федеративной стороне сервера баз данных DB2.
CREATE TABLE bookstore1(isbn CHAR(10), xmlinfo XML);
|
Вторая таблица расположена в базе данных Oracle 10g Release 2. Ее определение представлено ниже:
CREATE TABLE bookstore2(isbn CHAR(10), xmlinfo XMLTYPE);
|
Ограничения на таблицы, хранящиеся в двух базах данных, накладываются с помощью одной и той же удаленной схемы XML.
Таблица REVIEW хранится в базе данных на сервере MS SQL Server 2005 и содержит обзоры книг. Таблица определяется следующим образом:
CREATE TABLE review(review id INT, xmlinfo XML);
|
Таблица CUSTOMER INFO хранится в базе данных DB2 9 и содержит информацию о клиентах. Ниже представлено определение таблицы:
CREATE TABLE customer info(customer id INT, xmlinfo XML);
|
Таблицы INVENTORY и WAREHOUSE представляют собой реляционные таблицы, хранящиеся в базе данных DB2 9:
CREATE TABLE warehouse(warehouse id INT, street CHAR(50), city CHAR(30), state CHAR(30));
CREATE TABLE inventory(inventory id INT, warehouse id INT, isbn CHAR(10), quantity INT);
|
Информация об онлайновых заказах хранится в документах XML в локальной файловой системе под именем orders.xml.
A3. Создание надстроек, серверов и соответствий пользователей для сценария распределенной книготорговой фирмы
Нам необходимо определить четыре надстройки для доступа к источникам данных четырех различных типов:
CREATE WRAPPER net8;
CREATE WRAPPER drda;
CREATE WRAPPER mssqlodbc3;
CREATE WRAPPER xml wrapper LIBRARY 'libdb2lsxml.a'; |
Примечание: Наш сценарий был проверен на AIX 5.2.
После того, как на федеративной системе зарегистрированы библиотеки надстроек, необходимо зарегистрировать каждый из источников данных в качестве сервера:
CREATE SERVER "oracle10g2" TYPE ORACLE VERSION 10.2
WRAPPER net8 OPTIONS (NODE 'MYORA10');
CREATE SERVER "db2v91" TYPE db2/cs VERSION 9
WRAPPER drda AUTHORIZATION "myuser" PASSWORD "secret"
OPTIONS (NODE 'MYDB2', DBNAME 'MYDB');
CREATE SERVER "mssql" TYPE MSSQLSERVER VERSION 2005
WRAPPER mssqlodbc3 OPTIONS (NODE 'MYMSSQL', DBNAME 'MYDB');
CREATE SERVER "xml server" WRAPPER xml wrapper;
|
Далее, при необходимости, можно установить соответствие пользователей для регистрации аутентификационной информации доступа к удаленным источникам данных:
CREATE USER MAPPING FOR USER SERVER "oracle10g2"
OPTIONS (REMOTE AUTHID 'myuser', REMOTE PASSWORD 'secret');
CREATE USER MAPPING FOR USER SERVER "db2v91"
OPTIONS (REMOTE AUTHID 'myuser', REMOTE PASSWORD 'secret');
CREATE USER MAPPING FOR USER SERVER "mssql"
OPTIONS (REMOTE AUTHID 'myuser', REMOTE PASSWORD 'secret'); |
A4. Заполнение таблиц для примера распределенной книготорговой сети
После того, как будут созданы удаленные таблицы в соответствии с описанием, приведенным в разделе Сценарий распределенной книготорговой сети, их можно наполнить проверочными данными.
Таблица BOOKSTORE1, хранящаяся на федеративном сервере, содержит следующие данные:
% DB2 Federated Server
INSERT INTO bookstore1 VALUES('0201633469',
'<book isbn="0201633469" year="1993" category="Computers">
<title>TCP/IP Illustrated</title>
<author>
<last>Stevens</last>
<first>W. Richard</first>
</author>
<publisher>Addison-Wesley Professional</publisher>
<price>65.00</price>
</book>');
|
Заполнение таблицы BOOKSTORE2, хранящейся на сервере Oracle 10g Release 2, производится с помощью следующей команды:
% Oracle 10g Release 2
INSERT INTO bookstore2 VALUES('0201563177', XMLTYPE(
'<book isbn="0201563177" year="1992" category="Computers">
<title>Advanced Programming in the UNIX environment</title>
<author>
<last>Stevens</last>
<first>W. Richard</first>
</author>
<publisher>Addison-Wesley Professional</publisher>
<price>65.95</price>
</book>'));
|
Таблица REVIEW, хранящаяся на MS SQL Server 2005, заполняется следующим образом:
INSERT INTO review VALUES
(1,
'<reviews>
<review id="10001" isbn="155860622X">A very good discussion of
semi-structured database systems and XML.</review>
<review id="10002" isbn="0201563177">A clear and detailed discussion
of UNIX programming.</review>
<review id="10003" isbn="0201633469">One of the best books on
TCP/IP.</review>
</reviews>');
|
Следующие команды добавляют данные в таблицу CUSTOMER INFO, расположенную в базе данных DB2 9:
INSERT INTO customer info VALUES(1, XMLPARSE(DOCUMENT
'<customer id="1">
<name><last>Smith</last><first>Joe</first></name>
<address>
<street>6127 Crown Bld</street>
<city>San Jose</city>
<state>CA</state>
</address>
</customer>' PRESERVE WHITESPACE));
INSERT INTO customer info VALUES(2, XMLPARSE(DOCUMENT
'<customer id="2">
<name><last>Miller</last><first>Bob</first></name>
<address>
<street>544 Capitol Expw</street>
<city>San Jose</city><state>CA</state>
</address>
</customer>' PRESERVE WHITESPACE));
INSERT INTO customer info VALUES(3, XMLPARSE(DOCUMENT
'<customer id="3">
<name><last>Meyer</last><first>Ann</first></name>
<address>
<street>8400 Main St</street>
<city>San Francisco</city><state>CA</state>
</address>
</customer>' PRESERVE WHITESPACE));
INSERT INTO customer info VALUES(4, XMLPARSE(DOCUMENT
'<customer id="3">
<name><last>Apple</last><first>Sue</first></name>
<address>
<street>2200 Diamond Blvd</street>
<city>New York</city><state>NY</state>
</address>
</customer>' PRESERVE WHITESPACE)); |
Таблицы INVENTORY и WAREHOUSE, расположенные в одной и той же базе данных, заполняются данными следующим образом:
INSERT INTO warehouse VALUES (1, '1234 Market Street', 'San Francisco', 'CA');
INSERT INTO warehouse VALUES (2, '4012 1st Street', 'San Jose', 'CA');
INSERT INTO inventory VALUES (1001, 1, '0201633469', 3);
INSERT INTO inventory VALUES (1002, 1, '0201563177', 2);
INSERT INTO inventory VALUES (1003, 2, '0201633469', 1);
INSERT INTO inventory VALUES (1004, 2, '0201563177', 5); |
Информация об онлайновых заказах хранится в документах XML в локальной файловой системе под именем orders.xml, и содержит следующие данные:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<order id="101" cid="1" date="2004-10-24">
<item isbn="0201633469"/>
<item isbn="0201633469"/>
</order>
<order id="102" cid="3" date="2004-10-25">
<item isbn="0201633469"/>
</order>
<order id="103" cid="2" date="2004-10-26">
<item isbn="0201633469"/>
<item isbn="0201563177"/>
</order>
<order id="104" cid="1" date="2004-10-27">
<item isbn="0201563177"/>
</order>
<order id="105" cid="3" date="2004-10-28">
<item isbn="0201563177"/>
<item isbn="0201563177"/>
</order>
</orders> |
Ресурсы Научиться
- Оригинал статьи: Use WebSphere Federation Server Version 9.1 to integrate XML data.
- Попробуйте создать систему упорядоченных отчетов на базе XML и затем объединить данные из локальной базы данных и двух других источников данных, описанных в этом руководстве, Hello World, часть 9: WebSphere Federation Server: Простой доступ и объединение распределенных данных - где бы они не находились.
- "Использование технологии объединения данных в IBM WebSphere Information Integrator: Проектирование и настройка объединения данных" (developerWorks, июнь 2005 г.): Эта статья, написанная Э. Бетавадкар-Норвуд (A. Betawadkar-Norwood), Э. Лин (E. Lin) и И. Урсу (I. Ursu), познакомит вас с основными понятиями объединения данных и вопросами проектирования и настройки WebSphere Information Integrator.
-
"Использование технологии объединения данных в IBM WebSphere Information Integrator: Примеры использования объединения данных и оптимизация производительности" (developerWorks, июнь 2005 г.): В этой статье, написанной Э. Бетавадкар-Норвуд (A. Betawadkar-Norwood), Э. Лин (E. Lin) и И. Урсу (I. Ursu), обсуждаются вопросы оптимизации федеративных запросов, приводятся примеры использования и обсуждаются вопросы повышения производительности WebSphere Information Integrator.
-
"Руководство администратора IBM WebSphere Information Integration для федеративных систем": Эта книга представляет собой базовую документацию по продукту WebSphere Federation Server.
-
"Обзор продукта: IBM WebSphere Federation Server V9.1": Посетите этот сайт, если узнать больше о WebSphere Federation Server.
-
"Справочник по SQL в DB2 UDB, том 1" и "Справочник по SQL в DB2 UDB, том 2": Эти книги являются основными справочниками по SQL при работе с DB2 под управлением Linux™, UNIX® и Windows®.
-
"Создание запросов к данным XML в DB2 с помощью SQL" Синтия М. Саракко (Cynthia M. Saracco): Узнайте, как составлять запросы к данным, хранящимся в полях XML, с помощью SQL и SQL/XML.
-
"Создание запросов к данным XML в DB2 с помощью XQuery " Дон Чемберлин (Don Chamberlin) и Синтия М. Саракко (Cynthia M. Saracco): Узнайте, как составлять запросы к данным, хранящимся в полях XML, с помощью XQuery.
-
Руководство по pureXML в DB2 9 : В этом руководстве IBM приводится подробное описание реализации pureXML в DB2 9.
-
Раздел Information Management сайта developerWorks Россия: Узнайте больше о DB2. Здесь вы найдете техническую документацию, статьи с инструкциями, учебные материалы, материалы для скачивания, информацию о продуктах и многое другое.
-
Семинары и обучение на IBM developerWorks Россия.
Получить продукты и технологии
Обсудить
Об авторах  | 
|  |
Иоана Урсу (Ioana Ursu) работает программистом-консультантом в Silicon Valley Laboratory в Сан-Хосе, штат Калифорния. Она начала работу в лаборатории IBM в Альмадине в 1998 году в рамках исследовательского проекта Garlic.С 1999 года она работала над различными проблемами компиляции федеративных запросов, в том числе в области семантического анализа запросов, исправления запросов, анализа очередей и оптимизации запросов. Сегодня она работает в группе WebSphere Information Integrator Federated Query Compiler, в основном занимаясь общими вопросами обработки федеративных запросов. |
 | 
|  |
Доктор Эйлин Лин (Eileen Lin) является старшим техническим специалистом в Silicon Valley Laboratory в Сан-Хосе, штат Калифорния. Она была одним из первых участников разработки федеративной базы данных DataJoiner, которая стала предшественницей технологии объединения данных в DB2. На сегодняшний день она является архитектором по технологиям объединения данных в WebSphere Information Integrator. У доктора Лин множество патентов в различных областях, таких как технологии объединения, оптимизация запросов и параллельная обработка запросов. |
 | 
|  |
Аакаш Бордиа (Aakash Bordia) работает инженером-программистом в Silicon Valley Laboratory в Сан-Хосе, штат Калифорния. По окончании Университета Иллинойса в январе 2000 года он присоединился к группе разработчиков IBM DB2 Warehouse Manager и принимал участие в разработке преобразований хранилища данных с помощью SQL. В 2002 году он перешел в группу WebSphere Information Integrator Federation, где был разработчиком компилятора. В последнее время он занимается тем, что нервирует разработчиков, ломая их код и фиксируя дефекты (это называется инженер по обеспечению качества). |
 | 
|  |
Себастьян Ханель (Sebastian Hahnel) проходит стажировку в IBM Silicon Valley Lab в Сан-Хосе, штат Калифорния. Они присоединился к группе WebSphere Information Integrator Federation в апреле 2006 года после завершения с отличием курса информатики в Университете прикладных наук в Лейпциге, Германия. |
Выскажите мнение об этой странице
|  |