2011-01-27 2 views
0

Я пишу некоторые хранимые процедуры отчетности и нуждаюсь в анализе некоторых XML в SQL 2008. Это для системы CMS Umbraco, которая хранит свои данные с версией особым способом, который не подходит для запроса многих столбцов. Он также сохраняет XML-кеш всех опубликованных элементов, что, похоже, больше подходит для запросов.SQL - литье в xml-тип данных без использования временной таблицы?

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

Пример SP ниже - в котором используется временная таблица. Дополнительные точки для любых указателей на повышение эффективности при извлечении значений.

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

-- Create temporary table that uses the XML data type 
create table #XmlTable (
NodeId int, 
NodeXml xml 
) 

-- Move all XML for documents of type '1121' into there 
insert into #XmlTable(NodeId, NodeXml) 
select cx.* from cmsContentXml cx 
join cmsContent cc on cc.nodeId = cx.nodeId 
where cc.contentType = 1121 

select un.text [Document Name], 
xt.NodeXml.query('//node/data [@alias=''fieldOne'']').value('.', 'nvarchar(max)') [Field One], 
xt.NodeXml.query('//node/data [@alias=''fieldTwo'']').value('.', 'nvarchar(max)') [Field Two], 
xt.NodeXml.query('//node/data [@alias=''fieldThree'']').value('.', 'nvarchar(max)') [Field Three] 

from #XmlTable xt 
join umbracoNode un on un.id = xt.NodeId 

-- Drop temporary table when finished 
drop table #XmlTable 

Каждый XML-узел выглядит примерно так:

<node id="111"> 
    <data alias='fieldOne'>Value 1</data> 
    <data alias='fieldTwo'>Value 2</data> 
    <data alias='fieldThree'>Value 3</data> 
    <data alias='fieldFour'>Value 4</data> 
    <data alias='fieldFive'>Value 5</data> 
</node> 

Спасибо заранее.

+3

Там нет ничего плохого или медлит временных таблиц. Я бы не переписал его, чтобы избежать временных таблиц. – Andomar

ответ

2

Вот рабочий образец. Просто вставьте его в качестве подзапроса и выполните двойное преобразование nvarchar-> xml.

create table cmsContentXml(nodeid int, nodexml ntext) 
insert cmsContentXml 
select c, ' 
    <node id="' + right(c, 10)+ '"> 
     <data alias=''fieldOne''>Value ' + right(c * 100 + 1, 10)+ '</data> 
     <data alias=''fieldTwo''>Value ' + right(c * 100 + 2, 10)+ '</data> 
     <data alias=''fieldThree''>Value ' + right(c * 100 + 3, 10)+ '</data> 
     <data alias=''fieldFour''>Value ' + right(c * 100 + 4, 10)+ '</data> 
     <data alias=''fieldFive''>Value ' + right(c * 100 + 5, 10)+ '</data> 
    </node>' 
from (values(1),(2),(3),(4),(5)) t(c) 

create table umbracoNode(id int, text varchar(100)) 
insert umbracoNode values (1, 'test1'), (2, 'test2'), (1, 'test3') 

select un.text [Document Name], 
xt.NodeXml.query('//node/data [@alias=''fieldOne'']').value('.', 'nvarchar(max)') [Field One], 
xt.NodeXml.query('//node/data [@alias=''fieldTwo'']').value('.', 'nvarchar(max)') [Field Two], 
xt.NodeXml.query('//node/data [@alias=''fieldThree'']').value('.', 'nvarchar(max)') [Field Three] 
from (
    select cx.nodeid, convert(xml,convert(nvarchar(max),cx.nodexml)) nodexml 
    from cmsContentXml cx 
    ) xt join umbracoNode un on un.id = xt.NodeId 

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

Выход

Document Name Field One Field Two Field Three 
test1   Value 101 Value 102 Value 103 
test3   Value 101 Value 102 Value 103 
test2   Value 201 Value 202 Value 203 
1

Переключение таблицы переменных может улучшить производительность, как:

  • табличные переменные не вошли (не участвуют в сделке)
  • SP с временные таблицы не могут быть предварительно скомпилированных, но те, с таблицей переменными могут быть
  • нО, если есть большое количество строк, временные таблицы будут гораздо быстрее, так как вы можете индексировать их
Смежные вопросы