Программирование >>  Программирование баз данных 

1 ... 194 195 196 [ 197 ] 198 199 200 ... 346


Директивы id, idref и idrefs

Ни одна из директив id, idref и idrefs не выполняет каких-либо действий, если в сочетании с ними не используется также опция XMLDATA (которая должна следовать за опцией EXPLICIT в конструкции FOR XML). Еще одна особенность применения этих директив состоит в том, что с их помощью формируются документы, предназначенные для проверки по схеме, которая содержит соответствующие объявления. Причина, по которой применяется такая организация работы, становится вполне очевидной после анализа назначения этих директив. Ведь с их помощью вводятся дополнения к схеме, позволяющие осуществить проверку определенных характеристик документа, но само проведение такой проверки без схемы невозможно.

Дело в том, что применение конструкции FOR XML обеспечивает возможность включения в документ атрибутов id. Такие атрибуты id выполняют в до1сументе XML функции, аналогичные функциям первичных ключей в реляционных данных, поскольку с их помощью назначается уникальный идентификатор для элемента документа XML, с именем которого связан идентификатор id. Но ни для одного имени элемента не допускается указание в определении id больше одного атрибута. Имя атрибута, предназначенного для использования в качестве идентификатора id, определяется в схеме для формируемого документа XML. А после того как будет объявлен один элемент с указанным значением в качестве атрибута id, становится невозможным создание какого-либо элемента с тем же именем, имеющего такое же значение атрибута.

В отличие от первичных ключей, применяемых в реляционных объектах и обрабатываемых с помощью операторов SQL, в документе XML не допускается применение нескольких атрибутов в составе идентификатора id (поскольку не предусмотрены конструкции, аналогичные составньы! ключам).

Тем не менее конструкция FOR XML позволяет формировать атрибуты, которые по своему назначению аналогичны первичным ключам, поэтому не удивительно, что конструкция FOR XML позволяет также формировать атрибуты, которые могут применяться по аналогии с внешними ключами. Для этой цели предназначены директивы idref и idrefs, которые служат для создания ссылки, связывающей определенный атрибут одного элемента с атрибутом id другого элемента.

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

Необходимость в использовании для формирования подобных связей двух директив, idref и idrefs, обусловлена тем, что формируемые связи могут относиться к разным типам. Различия между директивами idref и idrefs подчеркиваются разной структурой их имен. Директива idref предоставляет единственное значение, которое должно согласовываться со значением id существующего элемента. С другой стороны, директива idrefs позволяет получить многозначное значение, представленное в виде разделенного пробелами списка, каждый элемент которого также должен согласовываться со значением id существующего элемента. Таким образом.



атрибуты idref используются, если есть необходимость установить связь один ко многим (возможно наличие в документе только по одному из всех значений id, т.е. значения id должны быть уникальными, но количество элементов с тем же значением атрибута idref не ограничивается). С другой стороны, атрибуты idref s используются, если необходимо установить связь многие ко многим (каждый элемент с атрибутом idref S может содержать ссылки на многие элементы с атрибутами id, указанными в значении idref s, а само количество элементов с атрибутами idref s, в которых указаны одни и те же значения id, не ограничено).

Чтобы проиллюстрировать использование рассматриваемых директив, необходимо внести небольшие изменения в предыдущий запрос. Вначале введем в действие директиву idref:

SELECT 1 as Tag,

NULL as Parent,

p.ProductID as [Product!1!ProductID!ID],

p.ProductSubcategorylD as [Product!1!ProductSubcategorylD! liide],

NULL as [Order!2!OrderlD],

NULL as [Order!2!ProductID!idref],

NULL as [Order!2lOrderDate]

FROM Production.Product AS p JOIN Sales.SalesOrderDetail AS sod ON p.ProductID = sod.ProductID JOIN Sales.SalesOrderHeader AS soh

ON sod.SalesOrderlD = soli.SalesOrderlD WHERE soli.OrderDate BETWEEN 2003-03-27 AND 2003-03-27

UNION ALL

SELECT 2, 1,

p.ProductID, p.ProductSubcategorylD, sod.SalesOrderlD, sod.ProductID, soli. OrderDate FROM Production.Product AS p JOIN Sales.SalesOrderDetail AS sod ON p.ProductID = sod.ProductID JOIN Sales.SalesOrderHeader AS soh

ON sod.SalesOrderlD = soli.SalesOrderlD WHERE soli.OrderDate BETWEEN 2003-03-27 AND 2003-03-27 ORDER BY [Product!1!ProductSubcategorylD1 liide] , [Product!11ProductID!ID],

[0rder!2!0rderID] FOR XML EXPLICIT, XMLDATA

После просмотра полученных результатов обнаруживается, что фактически в них интерес представляют только два фрагмента- схема и элемент Product:

<Sc]iema name= Scliemal xmlns= urn: scliemas -microsoft - com: xml - data xmlns :dt= urn: scliemas-microsof t-com:datatypes > <ElementType name= Product content= mixed model= open > <AttributeType name= ProductID dt:type= id /> <attribute type= ProductID /> </ElementType>

<ElementType name= Order content= mixed model= open > <AttributeType name= OrderlD dt:type= i4 /> <AttributeType name= ProductID dt:type= idref /> <AttributeType name= OrderDate dt:type= dateTime /> <attribute type= OrderlD /> <attribute type= ProductID /> <attribute type= OrderDate /> </ElementType> </Scliema >



В самой схеме присутствует некоторая довольно характерная информация о типе. Элемент Product объявлен как принадлежащий к типу элемента. Кроме того, обнаруживается, что элемент ProductID объявлен как выполняющий функции атрибута id для элемента этого типа. Аналогичным образом, элемент Order объявлен как имеющий атрибут ProductID, который относится к типу idref.

Следующим фрагментом, представляющим интерес, является элемент Product:

<Product xmlns= x-schema:#Schemal ProductID= 779 >

<Order OrderID= 49775 ProductID= 779 OrderDate= 2003-03-27T00:00:00 /> </Product>

В данном случае заслуживает внимания то, что в коде, сформированном в СУБД SQL Server, имеется ссылка на вложенную схему в объявлении элемента Product. Это равносильно объявлению о том, что элемент Product и все, что к нему относится, должно соответствовать схеме; таким образом, дается гарантия, что значения атрибутов id и idref всегда будут согласованы.

При осуществлении попытки применения директивы idrefs задача немного усложняется. Дело в том, что в СУБД SQL Server для формирования списка значений атрибутов idrefs требуется применение запроса, отдельного от того запроса, с помощью которого формируются элементы с атрибутами id. А в рассматриваемом примере мы должны выполнить не только это требование, но и ввести еще один запрос в состав конструкции с операцией UNION для подготовки значений атрибутов idrefs (поскольку список возможных значений атрибутов id должен быть известен до того, как мы приступим к формированию списка значений атрибутов idrefs, но фактические значения атрибутов id станут известны только после полного формирования атрибутов id). Запрос на формирование значений атрибутов idrefs должен непосредственно предшествовать запросу, в котором формируются значения атрибутов id. Таким образом, в своей окончательной форме запрос становится довольно замысловатым:

SELECT 1 as Tag,

IsnJLL as Parent,

p.ProductID as [Product!1!ProductID],

NULL as [Product mOrderList! idrefs] ,

NULL as [Orderl2lOrderlDlid],

NULL as [Order!2OrderDate]

FROM Production.Product p JOIN Sales.SalesOrderDetail AS sod ON p.ProductID = sod.ProductID JOIN Sales.SalesOrderHeader AS soh

ON sod.SalesOrderlD = soh.SalesOrderlD WHERE soh.OrderDate BETWEEN 2003-03-27 AND 2003-03-31

UNION ALL

SELECT 1,

NULL,

p.ProductID, soh.SalesOrderlD, NULL, NULL

FROM Production.Product AS p

JOIN Sales.SalesOrderDetail AS sod

ON p.ProductID = sod.ProductID JOIN Sales.SalesOrderHeader AS soh

ON sod.SalesOrderlD = soh.SalesOrderlD WHERE soh.OrderDate BETWEEN 2003-03-27 AND 2003-03-31

UNION ALL



1 ... 194 195 196 [ 197 ] 198 199 200 ... 346

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика