Конструкция OPENXML в T-SQL – описание и примеры

Всем привет! Сейчас мы рассмотрим возможность Microsoft SQL Server получать из XML данных привычные для нас табличные данные, иными словами, мы поговорим о том, как извлекать данные из XML документа. В языке T-SQL это реализуется с помощью специальной конструкции OPENXML.

Конструкция OPENXML в T-SQL

Ранее, в материале «Создание XML данных с помощью конструкции FOR XML», мы рассмотрели возможность SQL Server формировать XML документы на языке T-SQL, например, для того чтобы передавать их какому-нибудь клиентскому приложению. Сегодня мы научимся обрабатывать XML данные, которые поступают к нам, например, все от того же клиентского приложения. Если Вам необходимо просто сохранить XML документ, то, конечно же, извлекать из него данные необязательно, Вам достаточно сохранить их в таблице в столбце с типом данных XML. Но если Вам нужна информация, которая есть в этом XML документе, например, для ее сохранения в определённой табличной структуре, то Вам придётся обработать этот XML документ и извлечь из него соответствующие данные.

В Microsoft SQL Server извлечь данные из XML документа можно с помощью функции OPENXML.

OPENXML в Microsoft SQL Server

OPENXML – это специальная функция, которая извлекает данные из XML документа. Другими словами, она может на входе получить XML данные, а на выходе дать нам результирующий набор строк, как будто это результат запроса к обычным таблицам или представлениям. Эти данные мы, соответственно, можем сохранить или сразу провести какой-то анализ.

OPENXML — это не просто табличная функция, как было уже отмечено, это целая конструкция, так как чтобы использовать функцию, XML документ предварительно необходимо подготовить. А делается это с помощью системной хранимой процедуры sp_xml_preparedocument, которая проводит синтаксический анализ XML данных и возвращает дескриптор XML документа, который мы и передаем в функцию OPENXML для извлечения данных.

После того как мы извлечем данные, дескриптор XML документа необходимо удалить системной процедурой sp_xml_removedocument, для того чтобы освободить память. Можно этого и не делать, тогда в этом случае дескриптор будет существовать до конца сеанса (но чтобы избежать проблем с недостатком памяти, рекомендовано вручную удалять дескриптор, т.е. использовать процедуру).

Функция OPENXML имеет несколько параметров:

  • Первый – дескриптор XML документа;
  • Второй – шаблон на языке XPath, используемый для идентификации узлов, которые будут обрабатываться как строки;
  • Третий – тип сопоставления между XML данными и реляционными, например, 0 – используется атрибутивная модель сопоставления, это значение по умолчанию, 1 — использовать атрибутивную модель сопоставления, 2 — использовать сопоставление с использованием элементов, 8 — используемые данные не должны копироваться в свойство переполнения @mp:xmltext.

После функции, с помощью ключевого слова WITH, указывается формат набора выходных строк, т.е. мы перечисляем столбцы и их тип данных.

Примеры работы функции OPENXML в T-SQL

Для того чтобы посмотреть, как работает данная функция, давайте сначала сформируем XML документ, а затем извлечем из него данные в табличном виде. Для этого нам нужны данные, давайте их добавим.

Все примеры будут выполнены в Microsoft SQL Server 2016 Express.

Примечание! Начинающим рекомендую ознакомиться с материалом «Справочник по Transact-SQL».

Исходные данные для примера

   
   --Инструкция создания таблицы
   CREATE TABLE TestTable(
        [ProductId] INT IDENTITY(1,1) NOT NULL,
        [CategoryId] INT NOT NULL,
        [ProductName] VARCHAR(100) NOT NULL,
        [Price] MONEY NULL
   )
   GO
   --Инструкция добавления данных
   INSERT INTO TestTable
        VALUES (1,'Клавиатура', 100),
                   (1, 'Мышь', 50),
                   (2, 'Телефон', 300)  
   GO
   --Запросы на выборку
   SELECT * FROM TestTable

Скриншот 1

Извлечение данных из XML документа функцией OPENXML

Чтобы сформировать XML документ, мы используем конструкцию FOR XML. Затем с помощью функции OPENXML мы извлечем данные из полученного документа. Код в примере ниже я прокомментировал.

   
   --Объявляем переменные
   DECLARE @XML_Doc XML;
   DECLARE @XML_Doc_Handle INT;

   --Формируем XML документ
   SET @XML_Doc = (
                                SELECT ProductId AS "@Id", ProductName, Price
                                FROM TestTable
                                ORDER BY ProductId
                                FOR XML PATH ('Product'), TYPE, ROOT ('Products')
                                );
   --Подготавливаем XML документ
   EXEC sp_xml_preparedocument @XML_Doc_Handle OUTPUT, @XML_Doc;

   --Извлекаем данные из XML документа
   SELECT *
   FROM OPENXML (@XML_Doc_Handle, '/Products/Product', 2)
   WITH (
          ProductId INT '@Id', 
          ProductName VARCHAR(100),
      Price MONEY
      );
   --Удаляем дескриптор XML документа
   EXEC sp_xml_removedocument @XML_Doc_Handle;

Скриншот 2

В данном примере в переменной @XML_Doc мы сохранили XML документ, потом мы данную переменную передали на анализ системной процедуре sp_xml_preparedocument, которая вернула нам дескриптор XML документа в переменной @XML_Doc_Handle (если XML документ составлен синтаксически неправильно, выйдет ошибка).

В функцию OPENXML мы передаем переменную с дескриптором, указываем, какой элемент будет являться строкой, в нашем случае каждый элемент Product это строка, а также уточняем, какой метод сопоставления использовать, в нашем случае с использованием элементов.

В секции WITH мы перечислили название и тип итоговых столбцов, для ProductId мы указали дополнительный аргумент ‘@Id’ — это говорит о том, что данный столбец в XML документе является атрибутом Id.

После того как XML документ мы обработали, удаляем его дескриптор процедурой sp_xml_removedocument, передав в нее, соответственно, переменную с дескриптором.

Заметка! Для профессионального изучения языка T-SQL рекомендую посмотреть мои видеокурсы по T-SQL.

На этом все, пока!

Понравилась статья? Поделиться с друзьями:
Заметки IT специалиста
Комментарии: 1
  1. Dmitrii

    Привет!
    Отличная статья, очень сильно помогла понять принцип действия openxml.
    Остался единственный неясный момент по методам сопоставляния: как определить в каком случае какой метод лучше использовать?

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:
Нажимая на кнопку «Отправить комментарий», я даю согласие на обработку персональных данных и принимаю политику конфиденциальности.