|
Программирование >> Программирование баз данных
SELECT e.ContactID, COUNT(soh.SalesOrderlD) AS ©OrderCount FROM Person.Contact с JOIN Sales.SalesOrderHeader soh ON e.ContactID = soh.ContactID WHERE e.ContactID = 1 OR e.ContactID = 2 GROUP BY e.ContactID FOR XML PATH В данном случае было лишь решено снова предусмотреть оформление значений ContactID в виде отдельного элемента. На первый взгляд может показаться, что благодаря этому должен быть сформирован элемент ContactID, в котором данные столбца Order Count оформляются в виде атрибута, но эта попытка не совсем удается: Msg 6852, Level 16, State 1, Line 1 Attribute-centric column ©OrderCount must not come after a non-attribute-centric sibling in XML hierarchy in FOR XML PATH. Анализ возникшей при этом ситуации показывает, что СУБД фактически не может определить, атрибутом какого элемента должны стать данные столбца Order Count, - атрибутом элемента row или ContactID. Символ / Это действительно просто символ косой черты. Символ / (косая черта), во многом аналогично @, представляет собой специальный символ, который указывает, какие особые операции обработки документа должны быть выполнены. По существу, этот символ используется для определения своего рода пути доступа через иерархию документа, связывающего указанный элемент с теми компонентами документа, которые должны быть ассоциированы с ним. Этот символ может находиться в имени столбца на любой позиции, кроме первой. Для демонстрации применения символа / воспользуемся последним примером (который окончился неудачей) и введем его в том месте, где нужно вьшолнить поиск информации, при попытке получения которой возникла ошибка. Прежде всего необходимо внести изменения в конструкцию доступа к столбцу ContactID, чтобы получить информацию о том, какому элементу принадлежит этот столбец: SELECT e.ContactID, COUNT{soh.SalesOrderlD) AS ContactID/OrderCount FROM Person.Contact с JOIN Sales.SalesOrderHeader soh ON e.ContactID = soh.ContactID WHERE e.ContactID = 1 OR e.ContactID = 2 GROUP BY e.ContactID FOR XML PATH Строка, в которой находится символ /, а перед этим символом введено имя поля ContactID, служит для СУБД SQL Server указанием на то, что поле OrderCount находится в иерархии ниже поля ContactID. Поскольку предусмотрено много разных способов стр)тстуризации иерархии XML, рассмотрим, какие действия выполняются в СУБД SQL Server при осуществлении именно этого способа: < row ><ContactID>l< OrdeгCount > 7 </OrderCount ></ContactID ></row> < row > < Contact ID > 2 < Or de r Count > 4 < / Or de r Count >< / Cont actlDx / row > Напомним, что в предыд)щем примере было решено ввести значение OrderCount в качестве атрибута элемента ContactID, поэтому полученные результаты не соответствуют требованиям, которые были поставлены в этой задаче. Чтобы достичь намеченной цели, можно применить комбинацию символов / и @, но для этого не- обходимо определить всю иерархию. Однако, поскольку вполне можно предположить, что эта задача окажется сложной, разделим ее решение на два этапа, но вначале проверим такой вариант решения, который кажется подходящим для данного случая (однако приводит к получению фактически такого же сообщения об ошибке, как и в предыдущем примере): SELECT e.ContactID, COUNT(soh.SalesOrderlD) AS ContactID/@OrderCount FROM Person.Contact с JOIN Sales.SalesOrderHeader soh ON e.ContactID = soh.ContactID WHERE e.ContactID = 1 OR e.ContactID = 2 GROUP BY e.ContactID FOR XML PATH Ha этот раз сообщение об ошибке выглядит таким образом: Msg 6852, Level 16, State 1, Line 1 Attribute-centric column ContactID/@OrderCount must not come after a non-attribute-centric sibling in XML hierarchy in FOR XML PATH. Прежде чем приступить к устранению этой ошибки, рассмотрим внимательно, какие действия осуществляются при формировании дескрипторов XML с помощью конструкции FOR XML. Ключом к изучению выполняемых при этом действий становится понимание того, что дескрипторы по существу формируются в порядке их указания. Поэтому если требуется ввести в элемент атрибуты, то необходимо учесть, что атрибуты входят в состав дескриптора элемента, а это означает, что все атрибуты должны быть определены до того, как будет задано все прочее содержимое элемента (субэлементы или бесформатный текст). В данном случае решено помещать информацию поля ContactID в виде бесформатного текста, но значение Order Count должно быть представлено в виде атрибута (следует отметить, что в реальной практике данные операции могут выполняться в обратном порядке, но об этом немного позже). Это означает, что в СУБД SQL Server необходимые сведения передаются в обратном порядке. К тому времени как обнаруживается информация OrderCount, обработка атрибутов элемента ContactID уже заканчивается и возврат назад становится невозможным. Поэтому, чтобы исправить текущую ошибку, достаточно передать СУБД SQL Server информацию об атрибутах, прежде чем привести сведения о каких-либо др)тих элементах или бесформатном тексте: SELECT COUNT(soh.SalesOrderlD) AS ContactID/@OrderCount , e.ContactID FROM Person.Contact с JOIN Sales.SalesOrderHeader soh ON e.ContactID = soh.ContactID WHERE e.ContactID = 1 OR e.ContactID = 2 GROUP BY e.ContactID FOR XML PATH Такая конструкция применяемых операторов может показаться противоречащей здравому смыслу, но и в этом случае достаточно представить себе, в каком порядке происходит формирование конструкций в коде XML. Вначале формируются атрибуты, и лишь тогда и только тогда мы можем перейти к оформлению информации низкого уровня в элементе ContactID. Вызвав на вьшолнение приведенный выше вариант оператора, можно убедиться в том, что он позволяет достичь намеченной цели: <row><ContaetID OrderCount= 7 >l</ContaetID></row> <row><ContaetID OrderCount= 4 >2</ContaetID></row> Теперь информация о количестве заказов переместилась в позицию атрибута OrderCount, как и было задумано, а фактические данные об идентификаторе заказчика ContactID по-прежнему представлены в виде бесформатного текста, вложенного в элемент. Прослеживайте до конца логику упорядочения компонентов структуры, которая должна быть сформирована, поскольку этот подход позволяет успешно решать практически любые задачи. В частности, если бы потребовалось также задать значение ContactID в виде атрибута, а не бесформатного текста, но так, чтобы этот атрибут находился после атрибута OrderCount, то и данную задачу можно бьшо бы легко решить. Для этого достаточно предусмотреть, чтобы определение атрибута ContactID находилось после определения атрибута OrderCount. Дополнительные возможности применения символов @ и / Как уже было сказано выше, язык XPath сам по себе является достаточно сложным, и для его описания нужна отдельная книга, но автор хочет привести еще хотя бы некоторый объем информации, дополняющий предыдущее описание. Символы @ и / открывают широкий спектр возможностей, позволяющих формировать выходные данные в коде XML в полном соответствии с поставленными требованиями, поэтому конструкции, основанные на их использовании, по-видимому, соответствуют потребностям большинства приложений начального уровня. Если же требуется применение более сложных средств представления данных, то можно воспользоваться некоторыми описанными далее возможностями. Ниже приведен далеко не исчерпывающий список. Объединение данных по такому же принципу, который основан на использовании подстановочных символов, что позволяет представить всю выходную информацию в целом как текстовые данные, не требующие разделения на отдельные столбцы. Внедрение собственных данных XML, полученных из столбцов с типами данных XML. Применение средств проверки узлов языка XPath; таковыми являются специальные директивы XPath, позволяющие уточнять способы обработки данных. Использование директивы data () для обеспечения возможности представления в коде XML нескольких значений в виде одного многозначного значения. Использование пространств имен. Функция OPENXML Значительная часть настоящей главы посвящена описанию методов преобразования реляционных данных в данные, представленные в коде XML. Но из приведенного описания следует также вполне обоснованный вывод, что в СУБД SQL Server должна быть также предусмотрена возможность открыть строку кода XML и преобразовать содержащиеся в ней данные в табличный формат, подходящий для обработки с помощью языка SQL. OPENXML - это функция для работы с наборами строк, которая позволяет открыть переданную ей строку во многом на основе такого же принципа, по которому действуют
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |