Формирование xml произвольной структуры — различия между версиями
(→Введение) |
|||
(не показано 14 промежуточных версии этого же участника) | |||
Строка 1: | Строка 1: | ||
− | + | [[Работа с БД Oktell|Наверх]] | |
__TOC__ | __TOC__ | ||
==Введение== | ==Введение== | ||
− | + | В данной статье будет рассмотрено формирование xml структур. Необходимость в данном механизме возникает как правило из-за требований сторонних систем, либо когда необходимо вернуть массив данных в сценарии Oktell (Oktell может получать только набор столбцов одной строки). | |
Для этого будем использовать один из режимов для FOR XML, более подробно Вы можете ознакомиться по ссылкам: | Для этого будем использовать один из режимов для FOR XML, более подробно Вы можете ознакомиться по ссылкам: | ||
*[https://msdn.microsoft.com/ru-ru/library/ms189068(v=sql.105).aspx Использование режима EXPLICIT] | *[https://msdn.microsoft.com/ru-ru/library/ms189068(v=sql.105).aspx Использование режима EXPLICIT] | ||
Строка 35: | Строка 35: | ||
==Пример== | ==Пример== | ||
+ | |||
+ | Для примера сформируем xml структуру из таблицы oktell_settings.dbo.a_users из столбца [name] | ||
+ | |||
+ | |||
+ | [[Файл:rand_xml.jpg|center|1000px]] | ||
+ | |||
+ | |||
+ | |||
+ | <span style="color:red">ВНИМАНИЕ: При конструировании XML строки в универсальной таблице обрабатываются по порядку. Поэтому для получения правильных экземпляров потомков, связанных с их родителями строки в наборе строк должны быть упорядочены так, чтобы за каждым родительским узлом следовали его потомки (Сначала select 1 далее select 2.1 и последний select 3.1, изменение порядка повлечет создание другой xml структуры либо ошибку).</span> | ||
+ | |||
+ | Разберем результат: | ||
+ | |||
+ | 1)Существует элемент верхнего уровня (на рис. выделен зеленым цветом и цифрой 1), у которого 1 - tag и 0 - parent. | ||
+ | |||
+ | Для данного элемента перечислены столбцы sql запроса со следующими именами | ||
+ | *ElementName=request | ||
+ | *TagNumber=1 | ||
+ | *AttributeName = для разных столбцов - id,date или request_type. Данные имена атрибутов перечислены в request, за исключением id, т.к. его значение null, данный атрибут может понадобиться при наличии нескольких request. | ||
+ | *Directive - отсутствует | ||
+ | |||
+ | 2)Следующий элемент (на рис. выделен розовым цветом и цифрой 2) задается именем столбца указанном в 2 и содержит описание 2.1, у элемента 2 - tag и 1 - parent. Таким образом элемент request является для него родителем. | ||
+ | |||
+ | Для данного элемента перечислены столбцы sql запроса со следующими именами | ||
+ | *ElementName=person_data | ||
+ | *TagNumber=2 | ||
+ | *AttributeName = отсутствует | ||
+ | *Directive - отсутствует | ||
+ | |||
+ | 3)Последний элемент (на рис. выделен оранжевым цветом и цифрой 3) задается именем столбца указанном в 3 и содержит описание 3.1, у элемента 3 - tag и 2 - parent. Таким образом элемент person_data является для него родителем. | ||
+ | |||
+ | Для данного элемента перечислены столбцы sql запроса со следующими именами | ||
+ | *ElementName=person | ||
+ | *TagNumber=3 | ||
+ | *AttributeName = для разных столбцов: | ||
+ | **record_id - используется функция row_number() over (order by name) отображения id записи | ||
+ | **hash_last_name - значение name из таблицы oktell_settings.dbo.a_users | ||
+ | *Directive - отсутствует | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Текст запроса: | ||
+ | |||
+ | <pre> | ||
+ | select 1 as tag, | ||
+ | 0 as parent, | ||
+ | null as [request!1!id], | ||
+ | getdate() as [request!1!date], | ||
+ | 'Тип запроса' as [request!1!request_type], | ||
+ | null as [person_data!2!], | ||
+ | null as [person!3!record_id], | ||
+ | null as [person!3!hash_last_name] | ||
+ | |||
+ | union all | ||
+ | |||
+ | select 2 as tag, | ||
+ | 1 as parent, | ||
+ | null, | ||
+ | null, | ||
+ | null, | ||
+ | null, | ||
+ | null, | ||
+ | null | ||
+ | |||
+ | union all | ||
+ | |||
+ | select 3 as tag, | ||
+ | 2 as parent, | ||
+ | null, | ||
+ | null, | ||
+ | null, | ||
+ | null, | ||
+ | row_number() over (order by name), | ||
+ | name | ||
+ | from oktell_settings.dbo.a_users | ||
+ | |||
+ | for xml explicit | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | Данный запрос вы можете использовать для тренировки и построить xml структуры различного вида. |
Текущая версия на 12:06, 27 июля 2015
Содержание
Введение
В данной статье будет рассмотрено формирование xml структур. Необходимость в данном механизме возникает как правило из-за требований сторонних систем, либо когда необходимо вернуть массив данных в сценарии Oktell (Oktell может получать только набор столбцов одной строки). Для этого будем использовать один из режимов для FOR XML, более подробно Вы можете ознакомиться по ссылкам:
Режим FOR XML EXPLICIT
Режим EXPLICIT предоставляет наибольшую гибкость при формировании желаемого XML из результатов запроса. Запрос в режиме EXPLICIT должен быть написан особым способом, при котором в запросе явно задаются дополнительные сведения о требуемом XML, такие как ожидаемый уровень вложенности в XML. В зависимости от запрашиваемого XML написание запросов режима EXPLICIT может оказаться весьма трудоемким. Может оказаться, что использование режима PATH с вложениями является более простой альтернативой написанию запросов в режиме EXPLICIT.
Режим EXPLICIT преобразует набор строк, получаемый в результате выполнения запроса, в XML-документ. Для того чтобы режим EXPLICIT создал XML-документ, набор строк должен иметь определенный формат. То есть необходимо написать запрос SELECT для создания набора строк, универсальной таблицы, имеющей определенный формат, так чтобы логика обработки могла создать желаемый XML. Во-первых, запрос должен создавать следующие два столбца метаданных: первый столбец должен предоставлять номер тега текущего элемента (целочисленного типа), и этот столбец должен иметь имя Tag. В запросе должен быть указан уникальный номер тега для каждого элемента, который будет создан из набора строк; второй столбец должен задавать номер тега для родительского элемента, и этот столбец должен иметь имя Parent. Таким образом, столбцы Tag и Parent предоставляют сведения об иерархии. Значения этих столбцов метаданных вместе со сведениями в именах столбцов используются для создания желаемого XML. Обратите внимание на то, что имена столбцов в запросе должны задаваться особым образом. Также обратите внимание на то, что значение 0 или NULL в столбце Parent указывает на то, что у соответствующего элемента нет родителя. Такой элемент добавляется в XML в качестве элемента верхнего уровня.
При написании запросов в режиме EXPLICIT имена столбцов в результирующем наборе строк должны быть заданы с использованием описанного далее формата. Они предоставляют сведения о преобразовании, включая имена элементов и атрибутов и другие дополнительные сведения, задаваемые при помощи директив.
Общий формат имеет вид:
ElementName!TagNumber!AttributeName!Directive
,где
- ElementName - Результирующий общий идентификатор элемента. Например, если Customers задано в качестве ElementName, формируется элемент <Customers>.
- TagNumber - Уникальное значение тега, присвоенное элементу. Это значение с помощью двух метастолбцов, Tag и Parent, определяет вложенность элементов в результирующем XML.
- AttributeName - Предоставляет имя создаваемого атрибута для указанного элемента ElementName. Это поведение используется, если не задано значение Directive. Если задано значение Directive, имеющее тип xml, cdata или element, оно используется для создания дочернего элемента ElementName, к которому добавляется значение столбца. При указании значения Directive значение AttributeName может быть пустым. Например: ElementName!TagNumber!!Directive. В этом случае значение столбца напрямую содержится в ElementName.
- Directive - Значение Directive является необязательным и может использоваться для предоставления дополнительных сведений для создания XML.
Пример
Для примера сформируем xml структуру из таблицы oktell_settings.dbo.a_users из столбца [name]
ВНИМАНИЕ: При конструировании XML строки в универсальной таблице обрабатываются по порядку. Поэтому для получения правильных экземпляров потомков, связанных с их родителями строки в наборе строк должны быть упорядочены так, чтобы за каждым родительским узлом следовали его потомки (Сначала select 1 далее select 2.1 и последний select 3.1, изменение порядка повлечет создание другой xml структуры либо ошибку).
Разберем результат:
1)Существует элемент верхнего уровня (на рис. выделен зеленым цветом и цифрой 1), у которого 1 - tag и 0 - parent.
Для данного элемента перечислены столбцы sql запроса со следующими именами
- ElementName=request
- TagNumber=1
- AttributeName = для разных столбцов - id,date или request_type. Данные имена атрибутов перечислены в request, за исключением id, т.к. его значение null, данный атрибут может понадобиться при наличии нескольких request.
- Directive - отсутствует
2)Следующий элемент (на рис. выделен розовым цветом и цифрой 2) задается именем столбца указанном в 2 и содержит описание 2.1, у элемента 2 - tag и 1 - parent. Таким образом элемент request является для него родителем.
Для данного элемента перечислены столбцы sql запроса со следующими именами
- ElementName=person_data
- TagNumber=2
- AttributeName = отсутствует
- Directive - отсутствует
3)Последний элемент (на рис. выделен оранжевым цветом и цифрой 3) задается именем столбца указанном в 3 и содержит описание 3.1, у элемента 3 - tag и 2 - parent. Таким образом элемент person_data является для него родителем.
Для данного элемента перечислены столбцы sql запроса со следующими именами
- ElementName=person
- TagNumber=3
- AttributeName = для разных столбцов:
- record_id - используется функция row_number() over (order by name) отображения id записи
- hash_last_name - значение name из таблицы oktell_settings.dbo.a_users
- Directive - отсутствует
Текст запроса:
select 1 as tag, 0 as parent, null as [request!1!id], getdate() as [request!1!date], 'Тип запроса' as [request!1!request_type], null as [person_data!2!], null as [person!3!record_id], null as [person!3!hash_last_name] union all select 2 as tag, 1 as parent, null, null, null, null, null, null union all select 3 as tag, 2 as parent, null, null, null, null, row_number() over (order by name), name from oktell_settings.dbo.a_users for xml explicit
Данный запрос вы можете использовать для тренировки и построить xml структуры различного вида.