|
|
|||||||||||||||||||||||||||||
|
Запрос XML-данных в среде DB2 при помощи языка SQL (исходники)Источник: IBM developerWorks Россия Синтия M. Саракко (Cynthia M. Saracco)
Хотя гибридная архитектура DB2 обнаруживает значительные отличия от предыдущих версий, использование новых инструментов для работы с XML не должно вызывать трудностей. Если вы уже хорошо разбираетесь в SQL, то можете сразу же применить свои навыки для работы с XML-данными, которые хранятся в DB2 с характерными для этого формата особенностями. О способах выполнения читайте в нашей статье. Инструменты для работы с XML-данными DB2 Viper включают обновленную поддержку управления хранилищами, индексации и языка запросов. Мы выясним, как создавать и выполнять запросы на выборку данных, хранимых в XML-столбцах, при помощи «чистого» SQL и SQL c расширениями XML (SQL/XML). В одной из следующих статей предполагается изучить поддержку языка XQuery, развивающегося отраслевого стандарта, в среде DB2, и подробно исследовать, в каких случаях использование этого языка будет наиболее полезным. Возможно, для вас будет неожиданной информация о том, что DB2 поддерживает двуязычные запросы, то есть запросы, в которых сочетаются выражения SQL и XQuery. Выбор используемого языка (или сочетания языков) зависит как от требований прикладной системы, так и от ваших навыков. Сочетание элементов двух языков в одном запросе не такая сложная задача, как можно подумать, а данный метод может предложить вам более сильные средства для поиска и объединения XML и традиционных SQL-данных. База данных для упражненийЗапросы, описанные в этой статье, обращаются к примерам таблиц, создание которых описано в статье "Что нового в DB2 Viper". Коротко: примеры таблиц "items" и "clients" определены в листинге 1:
Примеры XML-данных, включенных в столбец "items comments", показаны на рисунке 1, а примеры XML- данных, включенных в столбец "clients contactinfo" - на рисунке 2. Последующие примеры запросов будут ссылаться на конкретные элементы одного или сразу обоих документов XML. Рисунок 1. Пример документа XML сохранен в столбце "comments" таблицы "items" Рисунок 2. Пример документа XML сохранен в столбце "contactinfo" таблицы "clients" Среда запросаВсе запросы в этой статье разработаны для того, чтобы вы могли повторить их на своем компьютере; это можно сделать либо через обработчик командной строки DB2, либо через редактор команд DB2 Command Editor модуля DB2 Control Center. Изображения снимков экрана и инструкции в данной статье относятся ко второму варианту (DB2 Viper поставляется со средой разработчика Developer Workbench на базе платформы Eclipse, что может помочь программисту конструировать запросы наглядным способом. В этой статье проблемы разработки приложений в среде разработки Developer Workbench не рассматриваются). Для использования редактора команд DB2 Command Editor, откройте Control Center и выберите команду Tools > Command Editor. На экране появится окно, показанное на рисунке 3 . В верхней панели введите запрос, затем нажмите зеленую стрелку в верхнем левом углу, чтобы выполнить его, и просмотрите полученные результаты в нижней панели или на отдельной вкладке "Query Results". Рисунок 3. Окно DB2 Command Editor, которое может быть вызвано из DB2 Control Center Запросы с использованием только языка SQLДаже если ваши знания языка SQL не слишком обширны, вы можете, затратив некоторые усилия, создать запрос на выборку XML-данных. Например, следующим запросом осуществляется выборка всего содержимого таблицы "clients", включая XML-информацию, хранимую в столбце "contactinfo": Листинг 2. Простое предложение SELECT
Конечно, вы можете писать более избирательные запросы SQL, содержащие операторы реляционной проекции и ограничения. Представленный в следующем листинге запрос осуществляет выборку идентификаторов, фамилий и контактной информации для всех клиентов, имеющих статус "Gold". Обратите внимание, что столбец "contactinfo" содержит XML-данные, а остальные два столбца - нет. Листинг 3. Простое предложение SELECT c проекцией и ограничением
И, как можно было бы предположить, есть возможность создавать представления на основе запросов, что демонстрируется в следующем листинге на примере представления "godview". Листинг 4. Создание представления, содержащего столбец XML
К сожалению, существует несколько ситуаций, в которых вы не сможете обойтись одним SQL. «Чистое» предложение SQL позволяет вам запросить XML-документ полностью (как вы только что убедились), но вы не можете определить предикаты запроса для XML, запросить часть XML-документа или определить значения элементов из какого-либо XML-документа. Другими словами, вы не можете выполнить операции ограничения, объединения, группировки или упорядочения фрагментов XML-документов при помощи «чистого» SQL. Например, невозможно получить только адреса электронной почты ваших клиентов со статусом "Gold" или фамилии клиентов, имеющих почтовый индекс "95116". Чтобы выполнить эти виды запросов, вам необходимо использовать SQL с расширениями XML (SQL/XML), XQuery или их сочетание. В следующем разделе рассматриваются несколько основных средств SQL/XML, а в одной из следующих статей мы изучим, как писать запросы XQuery и комбинировать XQuery c SQL. Запросы с использованием SQL/XMLКак видно из названия SQL/XML, данный язык был разработан, чтобы объединить сферы применения SQL и XML Он развивался как часть разработки стандарта SQL, и теперь включает спецификации для встраивания выражений XQuery и XPath в предложения SQL. XPath - это язык для навигации по документам XML с целью поиска элементов или атрибутов. Язык XQuery включает поддержку XPath. Важно отметить, что выражения XQuery (и XPath) являются регистрозависимыми. Например, запрос XQuery, который ссылается на элемент "zip", не будет применен к элементам XML, с именами "ZIP" или "Zip". Программисты SQL часто забывают о регистрозависимости языка, поскольку синтаксис запроса SQL позволяет использовать "zip", "ZIP" и "Zip" для ссылки на название одного и того же столбца. Программа DB2 Viper предоставляет более 15 функций SQL/XML, что позволяет осуществлять поиск конкретных данных в документах XML, преобразовывать реляционные данные в XML, и данные XML в реляционные данные, а также выполнять другие полезные задачи. Эта статья не охватывает в полной мере возможности языка SQL/XML, но мы рассматриваем некоторые распространенные задачи запросов и основные функции SQL/XML, которые позволяют решить эти задачи. "Ограничение" результатов по значениям элементов XMLПрограммисты SQL часто пишут запросы, ограничивающие возвращаемые из СУБД записи на основании некоторого условия. Например, запрос SQL, показанный в листинге 3 ограничивает возвращение записей, выбранных из таблицы "clients", таким образом, чтобы результаты включали только клиентов, имеющих статус "Gold". В этом случае статус клиента фиксируется в столбце SQL-типа VARCHAR. Но как поступить, если необходимо ограничить поиск на основании некоторого условия, которое следует применить к данным в столбце XML? Функция Давайте для примера рассмотрим решение поставленной ранее задачи. Представьте, что вам нужно найти фамилии всех клиентов, имеющих определенный почтовый код. Как вы помните, таблица "clients" хранит адреса клиентов (включая почтовые индексы) в столбце XML (См. рисунок 2.) При помощи Листинг 5. Ограничение результатов поиска на основании значения элемента XML
Первая строка предложения SQL определяет, что вы хотите получить только информацию из столбца "name" таблицы "clients". Предложение Распространенная ошибка влечет за собой формулирование предиката Листинг 6. Ограничение результатов поиска на основании значения элемента XML
Если этот запрос будет успешно выполнен, он не ограничит результаты поиска кругом клиентов, имеющих почтовый индекс 95116 (причина ошибки - в семантике языка, определенной в стандарте; это не является уникальным именно для DB2). Чтобы ограничить результаты поиска кругом клиентов, имеющих почтовый индекс 95116, необходимо использовать синтаксис, показанный ранее в листинге 5. Возможно, вас интересует, как включить запрос, ограничивающий результаты поиска XML-данных, в прикладную программу. Хотя в этой статье подробно не рассматривается тема разработки приложений, мы включили в нее простой пример на языке Java, который использует маркер параметра в предложении SQL/XML для ограничения вывода информацией только о тех клиентах, которые имеют данный почтовый индекс. "Проецирование" значения элемента XMLТеперь давайте рассмотрим слегка отличающуюся ситуацию, в которой вы предполагаете спроецировать значения XML на возвращаемое результирующее множество. Другими словами, требуется получить одно или более значений элементов из наших XML-документов. Существует несколько способов решить эту задачу. Давайте сначала воспользуемся функцией Рассмотрим решение сформулированной ранее задачи: как создать отчет, содержащий список адресов электронной почты клиентов со статусом "Gold". Запрос, представленный в следующем листинге 7 , для решения этой задачи вызывает функцию
В первой строке определяется, что вы хотите возвратить значения для вложенного элемента "email" корневого элемента "Client". Вторая и третья строки указывают, где DB2 может найти эту информацию - в столбце "contactinfo" таблицы "clients". Четвертая строка продолжает ограничивать запрос, указывая, что вас интересуют только адреса электронной почты клиентов со статусом "Gold". Этот запрос возвратит набор элементов XML и их значений. Например, если у вас есть 500 клиентов со статусом "Gold", причем каждый из них имеет один адрес электронной почты, вывод запроса будет представлять собой результирующее множество в виде одного столбца с 500 записями, как показано в листинге 8: Листинг 8. Пример вывода данных для предыдущего запроса
Если у вас имеется несколько адресов электронной почты для некоторых клиентов со статусом "Gold", то, возможно, вы захотите указать DB2, что нужно возвратить только основной адрес (то есть, первый из адресов электронной почты, найденный в документе "contactinfo" для данного клиента). Для этого вы можете изменить выражение XPath в первой строке запроса:
Наконец, если у вас нет адресов электронной почты для некоторых клиентов со статусом Gold, вам, возможно, захочется написать запрос, в результирующее множество которого включены нулевые значения. Чтобы получить этот результат, измените предыдущий запрос, добавив другой предикат в предложение
Теперь давайте рассмотрим несколько отличающуюся ситуацию, где вам нужно получить несколько значений элемента XML. Функция Рассмотрим следующий запрос (листинг 11), отображающий столбцы, содержащие и реляционные, и XML-данные, хранимые в таблице "items" (таблица "items" изображена на рисунке 1 .) Идентификатор комментария, идентификатор клиента и сообщения хранятся в XML-документах в столбце "comments". Названия объектов хранятся в столбце SQL, тип данных VARCHAR (строка).
Первая строка определяет столбцы, которые следует включить в результирующее множество. Столбцы, заключенные в кавычки с префиксом в виде переменной "t", создаются на основании значений элементов XML, в соответствии с указаниями последующих строк запроса. Вторая строка вызывает функцию На рисунке 4 показаны примеры результатов, полученных при выполнении этого запроса. Как мы видим, вывод представляет собой простое результирующее множество SQL. Обратите внимание - имена столбцов переведены в верхний регистр, что является обычным для SQL. Рисунок 4. Пример вывода запроса, использующего функцию XMLTable При желании вы можете использовать функцию
Создание реляционных представлений данных XMLЛегко догадаться, что функции SQL/XML могут использоваться для определения представлений. Это особенно полезно, если вы хотели бы обеспечить программистов приложений на языке SQL реляционной моделью ваших данных, хранимых в формате XML. Создание реляционного представления на основе данных в столбце XML ненамного сложнее, чем отображение значений элементов XML. Вы просто пишете предложение SQL/XML Листинг 13. Создание представления на основе вывода функции XMLTable
Хотя создание реляционных представлений на основе данных XML-столбцов не представляет особой сложности, все же следует пользоваться этой функцией с осторожностью. DB2 не использует индексы XML-столбцов, когда по таким представлениям создаются запросы. Так, если бы вы проиндексировали элемент ResponseRequest и создали запрос SQL, ограничивающий результаты тех столбцов, с которых следует получить ответы, определенным значением, программа DB2 просмотрела бы все документы XML в поисках соответствующего значения "ResponseRequest" Это снизило бы рабочую производительность, если, конечно, количество данных не слишком мало. Однако, если запрос, который вы планируете создать по таким представлениям, содержит также существенно ограничивающие предикаты, охватывающие индексированные столбцы традиционных типов SQL (в данном примере "i.id" или "i.itemname"), вы можете сократить проблемы со снижением рабочей производительности. DB2 использует реляционные индексы для фильтрации соответствующих критериям записей и снижения их количества, а затем применяет предикаты любых дополнительных запросов к этим предварительным результатам, прежде чем возвратить окончательное результирующее множество. Объединение данных XML и реляционных данныхТеперь вам, возможно, будет интересно объединение XML- и не-XML -данных (например, реляционных данных традиционных типов SQL). DB2 дает вам возможность сделать это одним предложением SQL/XML. Хотя существуют различные способы формулировки такого объединения, зависящие от схемы базы данных и требований к рабочей нагрузке, мы рассмотрим только один пример. Возможно, вы будете удивлены, если узнаете, что уже обладаете достаточными знаниями по SQL/XML, чтобы выполнить эту работу. Вспомните, что XML-столбец в таблице "items" содержит элемент "CustomerID". Он может служить объединяющим ключом для содержащего целые значения столбца "id" таблицы "clients". Так, если вы хотите получить отчет, содержащий фамилии и сведения о статусе клиентов, которые оставили комментарии по поводу одного или нескольких ваших продуктов, вам следует объединить значения элемента XML из одной таблицы с целыми значениями SQL из другой. И один из способов решить эту задачу - это воспользоваться функцией Листинг 14. Объединение XML- и не-XML-данных
В первой строке определяются столбцы SQL, которые следует включить в результирующее множество запроса и исходные таблицы, которые упоминаются в запросе. Вторая строка включает предложение объединения. Здесь Использование выражений "FLWOR" в SQL/XMLХотя мы уже обсудили несколько функций, SQL/XML предоставляет еще много эффективных средств для создания запросов на выборку XML-данных и объединения этих данных с реляционными данными. Действительно, мы уже видели несколько примеров того, как это работает, а теперь рассмотрим еще несколько применений. Обе функции - и Запросы XQuery могут содержать некоторые или все следующие операторы: " Давайте предположим, что нам нужно получить имена и основные адреса электронной почты клиентов со статусом "Gold". В некоторых отношениях эта задача похожа на одну из тех, что мы рассматривали раньше (см. листинг 9), когда изучали, как проецировать значения элемента XML. В следующем примере вы составите запрос XQuery (с предложениями " Листинг 15. Получение XML-данных при помощи предложений XQuery "for" и "return"
Первая строка определяет, что фамилия клиента и вывод функции Из-за того, что этот пример был таким простым, можно было бы написать здесь точно такой же запрос. Но вместо этого вы могли бы написать этот же запрос в более компактном виде, намного более компактном, чем до сих пор: Листинг 16. Более компактная запись предыдущего запроса
Однако предложение Листинг 17. Получение и преобразование данных XML в HTML
Первая строка показывает, что вас интересует текстовое представление первого из адресов электронной почты клиентов, соответствующих критериям запроса. Вторая строка определяет, что эта информация перед возвращением должна быть заключена в тэги HTML "параграф". В частности, фигурные скобки ({}) дают указание DB2 вычислить вложенное выражение (в данном случае, "$e"), а не рассматривать его как строку символов. Если вы пропустите фигурные скобки, DB2 возвратит результирующее множество, содержащее "<p>$e</p>" для каждой записи о клиенте, соответствующем критериям запроса. Публикация реляционных данных в виде XMLДо сих пор мы фокусировали внимание на способах запроса, извлечения или преобразования данных, содержащихся в XML-столбцах DB2. И, как вы могли убедиться, эти средства доступны в любом предложении SQL/XML. SQL/XML предоставляет также другие полезные функции. Среди них - возможность преобразовать или опубликовать реляционные данные в формате XML. В нашей статье описывается этот аспект для трех функций SQL/XML: Функция Листинг 18. Использование функции XMLElement для публикации реляционных данных в формате XML
Выполнение этого запроса генерирует результаты, представленные в листинге 19: Листинг 19. Пример вывода возвращаемых данных для предыдущего запроса
Вы можете комбинировать функцию Листинг 20. Агрегация и группировка данных
Предположим, наша таблица "clients" содержит три неповторяющихся значения "status": "Gold," "Silver," и "Standard." Выполнение предыдущего запроса заставит DB2 возвратить три элемента "customerList", каждый из которых может содержать несколько вложенных элементов "customer", с информацией о фамилии и статусе. Таким образом, вывод будет выглядеть так: Листинг 21. Пример вывода возвращаемых данных для предыдущего запроса
Операции удаления и измененияХотя в данной статье акцент делается на поиске и получении при помощи запросов SQL данных, хранимых в столбцах XML, имеет смысл уделить время нескольким моментам, позволяющим решить две другие распространенные задачи: изменение и удаление данных в столбцах XML. DB2 позволяет пользователям изменять и удалять XML-данные при помощи предложений SQL/XML. Действительно, поскольку первоначальный проект спецификации XQuery не решал этих задач, пользователи DB2 должны решать эти задачи с использованием SQL. Изменение XML-данныхDB2 позволяет изменять столбцы XML при помощи предложения SQL Например, если вы хотите создать предложение Рассмотрим следующее предложение: Листинг 22. Простое предложение UPDATE
Если вы помните, как мы выполняли вставку данных XML в статье "Getting off to a start start with DB2 Viper" (Начинаем работать с программой DB2 Viper), то многие из этих предложений должны показаться вам знакомыми. Как и любое предложение SQL Если вы выполните предыдущее предложение Листинг 23. Результат выполнения предыдущего предложения UPDATE
Адрес, номер телефона и номер факса данного клиента (см. рисунок 2) будут утеряны. Более того, некоторые из созданных ранее запросов, которые вы написали для извлечения адресов электронной почты клиентов, больше не возвратят данный адрес. Почему? Написанные ранее запросы включали выражения XPath или XQuery, которые проходили по определенной иерархии документа, в которой "Client" был корневым элементом, а "email" - вложенным элементом. После продемонстрированного изменения документа элемент "email" стал корневым элементом для данной XML-записи о клиенте, поэтому его значение не будет обнаружено в ожидаемом месте иерархии. Если вы хотите изменить адрес электронной почты данного клиента интерактивно и сохранить всю прочую имеющуюся контактную информацию, перепишите этот запрос так, как показано в листинге 24: Листинг 24. Отредактированное предложение UPDATE
Возможно, вам интересно, можно ли избежать определения полного XML-документа, выполняя изменения через представление. Например, представление "comment", определенное в листинге 13 , использует функцию Удаление XML-данныхУдаление записей, содержащихся в столбцах XML, представляет собой прямую процедуру. Предложение SQL Например, в следующем листинге показано, как можно удалить всю информацию для клиента с ID 3227: Листинг 25. Удаление данных для определенного клиента
Помните, как ограничить предложения SQL Листинг 26. Удаление данных для клиентов, имеющих определенный почтовый индекс
ИндексированиеИ наконец, ничего не стоит научиться создавать специализированные индексы XML для ускорения доступа к данным, хранимым в столбцах XML. Мы не будем рассматривать эту тему в данной статье из-за вводного характера статьи и недостаточного объема данных для упражнений. Однако, в производственной обстановке определение соответствующих индексов может быть критически важным для достижения оптимальной производительности. ЗаключениеВ статье были рассмотрены некоторые основы языка, при этом были особо отмечены отдельные ключевые аспекты SQL/XML и принципы их использования для создания и выполнения запросов на выборку данных в столбцах XML. Безусловно, при помощи функций SQL и SQL/XML можно сделать намного больше, чем мы смогли рассмотреть в этой статье. В статью включен простой пример на языке Java, демонстрирующий, как можно использовать маркеры параметров вместе с SQL/XML для запроса данных в столбцах XML. Более подробно мы рассмотрим проблемы разработки приложений в одной из следующих статей. А в следующей статье будут изучаться некоторые интересные аспекты нового языка запросов, поддерживаемого DB2 Viper - XQuery. Ссылки по теме
|
|