Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Использование XML совместно с SQL.doc
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
1 Мб
Скачать
☆

Метод value

Из предыдущих примеров уже должно быть понятно назначение этого метода. Его синтаксис:

value ('XQuery', SQLType [, noderef ])

  • XQuery – запрос XQuery.

  • SQLType – встроенный тип сервера.

  • noderef – ссылка на узел, относительно которого выполняется запрос.

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

select fams.*

from fams

where fam::value('/fam/husband/@income', 'int') > 180

В результате выбираются все семьи, мужья в которых имеют доход больше 180. Это менее эффективно, чем использование метода exist (особенно при наличии индекса), который я описываю далее:

select fams.*

from fams

where fam::exist('/fam/husband[@income > 180]') = 1

Метод exist

Метод exist возвращает значение типа bit, равное:

  • 1, если результат выборки не является пустой последовательностью;

  • 0, если результат является пустой последовательностью;

  • NULL, если данный XML-документ пустой.

Вот синтаксис этого метода:

exist ('XQuery' [, noderef ])

Здесь:

  • XQuery – запрос XQuery;

  • noderef - ссылка на узел, относительно которого выполняется запрос.

Метод modify

Этот метод позволяет выполнять изменяющие XML-документ команды, речь о которых пойдет в разделе XML DML.

Использование xml-типа

Так как XML-тип является встроенным типом, его можно использовать почти везде, где разрешено использование обычных типов.

Например, можно создать функцию, которая возвращает суммарный доход всех членов семьи:

create function dbo.FamIncomeSum(@xml xml) returns int

begin

return @xml::value('sum(/fam/*/@income)', 'int')

end

и использовать ее следующим образом:

select dbo.FamIncomeSum(fam)

from fams

На поля XML-типа можно накладывать ограничения (check constraints), например следующее ограничение не позволит вставить в таблицу fams семью, у элемента husband которой отсутствует атрибут @income (хотя лучше для таких целей использовать XSD):

create table fams(

id int identity primary key,

fam xml check(fam::exist('/fam/husband/@income') = 1)

)

Если вы еще не привыкли к XQuery (который я старался не использовать в предыдущих примерах, обходясь синтаксисом старого XPath 1.0), вы можете создать удобное представление (view) на основе XML-поля. Следующее view отображает некоторые данные таблицы fams в реляционном виде:

create view dbo.v_fams

as

select id,

fam::value('/fam/husband/@income', 'int') as HusbandIncome,

fam::value('/fam/wife/@income', 'int') as WifeIncome,

fam::value('/fam/son/@income', 'int') as SonIncome

from dbo.fams

К сожалению, на подобных представлениях нельзя строить кластерные индексы, поэтому единственным шансом повысить производительность запросов является построение специального XML-индекса.

XML-индекс

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

Синтаксис создания XML-индекса:

CREATE XML INDEX index_name

ON [ { database_name . [ schema_name ] . | schema_name . } ] table_name

( xml_column_name )

[ WITH ( <xml_index_option> [ , ...n ] ) ]

Где:

  • index_name – имя индекса. Имя индекса должно быть уникальным среди имен индексов данной таблицы.

  • xml_column_name – имя колонки XML-типа.

  • xml_index_option – опции XML-индекса. Здесь можно указывать те же опции, что и для простого индекса за исключением IGNORE_DUP_KEY, REBUILD и ONLINE.

При создании XML-индекса должны учитываться следующие ограничения:

  • Индекс может быть построен только для таблиц с кластерным ключом.

  • На одну колонку XML-типа невозможно построить более одного XML-индекса. Однако вы можете совмещать, например, полнотекстовый индекс и XML-индекс.

  • Невозможно создать индекс на переменную или на поле представления XML-типа.

  • Нельзя изменять тип XML-поля (изменение схемы данных для данного поля), если имеется связанный с ним XML-индекс.

  • Пример построения индекса для поля fam таблицы fams следующий:

create xml index XMLIX_fam on dbo.fams

Удаление индекса выполняется обычной командой drop index, правда, синтаксис ее в Yukon немного изменен по сравнению с SQL Server 2000:

drop index XMLIX_fam on dbo.fams

-- старый синтаксис - drop index dbo.fams.XMLIX_fam – не работает!