Февраль 2005


Профессионалу разработчику


Син Диллон

Совместное использование данных, представленных в виде XML
(Share Your Data as XML, By Sean Dillon)

Источник: журнал Oracle Magazine, no.1, 2005, http://www.oracle.com/technology/oramag/oracle/05-jan/o15xml.html

Сделайте существующие реляционные и объектные данные доступными как XML

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

История 101

Адаптирование к новым форматам данных или аккумулирование новых механизмов хранения не является чем-то новым в Oracle. В начале 1990-ых, объектно-ориентированные (OO) программисты поняли, что [кажущаяся] полная несовместимость между объектами, имеющими атрибуты данных, и реляционными таблицами со столбцами оказалась просто слишком сложной работой для команд разработчиков. Таким образом, началась то, что я называю Объектной Революцией (Object Revolution), в которой компании, разрабатывающие объектно-ориентированные базы данных, стали конкурировать с крупными производителями систем управления реляционными базами данных (RDBMS).

Oracle признала необходимость поддержки объектной технологии в своей базе данных, поэтому ею были предприняты некоторые шаги для ее реализации. Oracle внедрил виртуальную Java-машину в ядро базы данных; новую конструкцию базы данных, называемую Object Type или User-Defined Type (UDT); и, что наиболее важно, объектные представления. Объектные представления дали администраторам и разработчикам возможность создавать представления базы данных типа UDT, где результирующий набор – это коллекция объектов вместо набора реляционных строк.

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

История повторяется

Объекты все еще являются большой частью стратегии Oracle, и они полностью поддерживаются в Oracle Database 10g. Сегодня, однако, индустрия намного меньше сфокусирована на поддержке объектов (так как в основном это уже сделано). Также как в 1990-ых индустрия требовала поддержки объектов в базе данных, теперь она требует поддержки в базе данных XML-возможностей.

В готовящихся выпусках журнала Oracle Magazine колонка XML Exchange будет демонстрировать, как усовершенствовалась Oracle Database, чтобы обеспечить поддержку XML, а именно: новый тип данных XML, XML-поддержка программирования при синтаксическом разборе и XSL-преобразованиях, поддержка XML Schema и вариантов хранения XML. Нынешняя статья, однако, концентрируется только на одном аспекте новой функциональности базы данных: генерации XML. В течение Объектной Революции мы учились, как в базе данных сделать реляционные данные доступными в виде пользовательских типов. Сегодня в базе данных данные можно сделать доступными как XML. Давайте рассмотрим практический пример, как подготовить существующие реляционные и объектные данные в виде XML.

Реальная простая множественная публикация (syndication)

Многие популярные Web-сайты в настоящее время поддерживают поставку новостей в формате RSS (RSS расшифровывается как RDF Site Summary, Rich Site Summary или Real Simple Syndication, в зависимости от того, кого вы спросите). RSS – это легкий, гибкий XML-формат для выполнения одновременной публикации данных в нескольких изданиях.

Для Web-сайтов, которые используют эту технологию, данные, будучи предоставлены как RSS, обычно имеют одинаковое содержание, которое доступно на Web-сайте. Именно они имеют XML-формат. Почти во всех случаях эти данные порождаются из реляционных или объектных данных, использующихся в публикациях на существующих Web-сайтах. Когда новости публикуются как XML, средство, известное как RSS-считыватель, может считывать эти новости и добавлять их в консолидированный список новостей.

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

Рассмотрим модель данных, которая будет использоваться для публикации новостей. Для простоты будем использовать несколько таблиц и демонстрационных схем, включенных в Oracle9i Database и Oracle Database 10g. А именно, таблицы EMPLOYEES и DEPARTMENTS из демонстрационной схемы hr.

Используя эти простые таблицы, создадим RSS, которая покажет менеджеру пять сотрудников, принятых в отдел за последние время. Этот запрос очень прост. В данном случае мы запрашиваем пять сотрудников, принятых на работу в последнее время в отдел продаж (Sales) (ID отдела: 80):

select e.first_name, e.last_name,
 e.hire_date
 from (select first_name,
 last_name,
 hire_date,
 department_id
 from employees
 order by hire_date desc) e
 where department_id = 80
 and rownum < 6
/

Мы используем целую смесь из SQL/XML, PL/SQL и DBUri (с DBUri servlet), чтобы получить этот отчет опубликованным в формате RSS.

Сначала создадим PL/SQL-функцию, которая по ID отдела возвращает объект типа XMLType в формате RSS-документа, как показано на Листинге 1.

Листинг 1: PL/SQL-функция, которая возвращает объект типа XMLType в формате RSS-документа

create or replace function get_department_xml (p_department_id in number)
  return xmltype
as
  -- Используется для заполнения и возврата XML-документа
  l_xml xmltype;
begin
 -- Используется SQL/XML-запрос для генерации RSS-документа 
 -- и помещения его в локальную переменную l_xml.
  select xmlelement( "rss",
           xmlattributes( '0.91' as "version" ),
           xmlelement( "channel",
             xmlforest( 'Department New Hire Report' as "title",
                        'http://oramag.oracle.com' as "link",
                        p_department_id "description",
                        'en-us' as "language",
                        'Copyright 1999-2004, Oracle Corporation' 
                          as "copyright"
             ),
             xmlelement("image",
               xmlforest('Most Recently Hired Employees' as "title",
                         'http://asktom.oracle.com/i/asktom2.gif' 
                           as "url",
                         'http://oramag.oracle.com' "link",
                         '50' as "width",
                         '50' as "height",
                         'A sample RSS document showing new hires.'
                         as "description")
             ),
             ( select xmlagg(
                        xmlelement( "item",
                          xmlforest(x.first_name||' '|| 
                            x.last_name||', '||x.hire_date as "title",
                            '/oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=' ||
                              x.employee_id || ']' as "link",
                            x.hire_date as "description" ) ) )
                 from ( select e.first_name, e.last_name, e.hire_date, 
                               e.employee_id, d.department_name
                          from employees e, departments d
                         where d.department_id = p_department_id
                           and d.department_id = e.department_id
                         order by e.hire_date desc) x
                where rownum < 6 ) ) )
    into l_xml
    from dual;
  --
  return l_xml;
end get_department_xml;

Заметьте, что функции Листинга 1 – XMLElement(), XMLAttributes(), XMLForest() и XMLAgg() – являются частью SQL/XML, нового промышленного стандарта, который позволяет SQL-запросам возвратить XML-документ.

Функция XMLElement() создает XML-элемент в документе. Параметры, передаваемые этой функции, определяют, будет ли элемент содержать атрибуты или вложенную XML-разметку. Функция XMLAttributes() создает один и более атрибутов, вставленных в соответствующий элемент, а функция XMLForest() создает один и более дополнительных элементов. И, наконец, функция XMLAgg() агрегирует множество строк в коллекцию XML-узлов. Эти SQL/XML функции предоставляют все возможности, необходимые для создания многократно вложенных с неограниченной гибкостью XML-документов.

Следующий этап – создание представления типа XMLType, которое показывает RSS-документ для каждого DEPARTMENT_ID из таблицы DEPARTMENTS. Таблица DEPARTMENTS запрашивается для получения DEPARTMENT_ID, который затем передается в функцию GET_DEPARTMENT_XML, а ее результат отображается в представлении, возвращающем RSS-документ для каждой строки в таблице DEPARTMENTS:

create or replace view
dept_newhiresof
xmltype with object id (
 extract(object_value,
 '/rss/channel/description/text()')
.getnumberval()) as
 select get_department_xml(
 department_id)
 from departments
/

В этом SQL-предложении создается представление типа XMLType с названием DEPT_NEWHIRES. Каждое представление типа XMLType должно иметь уникальный Object ID, который служит уникальным идентификатором для каждой строки представления. Уникальный Object ID создается с помощью DEPARTMENT_ID, и использования выражения XPath ('/rss/channel/description/text()') из OBJECT_VALUE. OBJECT_VALUE – это псевдостолбец, который создается, когда запрашиваются строки представления. Теперь, когда представление создано, осталось вызвать его из Web-браузера.

Чтобы получить данные SQL-представления в Web, используется возможность базы данных, известная как DBUri Servlet. Она позволяет просматривать содержимое таблиц или представлений базы данных Oracle через Web. Наш DBUri-запрос выглядит следующим образом:

http://hr:hr@asktom.oracle.com:8080/oradb/HR/DEPT_NEWHIRES/ROW/rss[channel/description=80]

Для вызова этого DBUri Servlet используется четыре основных элемента:

  • Имя пользователя и пароль. Чтобы присоединиться к базе данных, в URL передается имя пользователя и пароль. Это позволяет вызвать URL из RSS-считывателя целиком, без ручного присоединения каждый раз, когда считыватель обновляет данные. В нашем примере используется пользователь HR с паролем HR (hr:hr).
  • Имя хоста и порт. Это имя хоста и порт, на котором запущен процесс-слушатель базы данных Oracle (Oracle database listener). В нашем случае используется порт 8080 сервера asktom.oracle.com.
  • DBUri-спецификация. Она приходит в формате /oradb/USERNAME/TABLE или VIEW. /oradb/ сообщает процессу-слушателю, что запрос для DBUri Servlet и USERNAME и TABLE или VIEW сообщают Servlet, какие данные надо получить. Мы используем представление DEPT_NEWHIRES схемы HR.
  • Ограничивающее выражение. Мы также передаем ограничивающее выражение, чтобы сообщить DBUri Servlet, как ограничить выполняемый запрос. Это выражение –Xpath-выражение, которое не только описывает корневой элемент для выбора из результирующего XML, но может также ограничить список возвращаемых XML-документов. Мы используем Xpath-выражение /DEPT_NEWHIRES/ROW/rss, которое возвращает элемент как корневой узел. Затем мы указываем, какой документ необходимо извлечь, с помощью [channel/description=80] части Xpath-выражения в скобках для уникальной идентификации отдела с ID 80.

В Web-браузере XML-результат нашего DBUri-запроса выглядит следующим образом:

- <rss version="0.91">
 - <channel>
 <title> Department New Hire Report</title>
...

Чтобы увидеть отформатированный результирующий XML, используйте RSS-считыватель, такой как Sage, RSS-считыватель, который встроен в Mozilla Firefox через его расширенные возможности. Мы добавляем этот URL в Sage как RSS, и получаем результат, показанный на Рис.1.

Рис 1: RSS XML, отображаемый в RSS-считывателе Sage

Пересоздание не требуется

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


Син Диллон (sean.dillon@oracle.com) - главный технолог и работает в Oracle с 1996г. Главный автор Beginning Oracle Programming (APress), Диллон специализируется на ядре базы данных, технологиях XML и Web-сервисов.

E-mail this page