2011-01-27 48 views
0

我正在編寫一些報告存儲過程,並且需要在SQL 2008中解析一些XML。它適用於Umbraco CMS系統,它以不適合查詢多列的特殊方式存儲其版本化數據。它也保留所有已發佈項目的XML緩存,這看起來更適合查詢。SQL - 不使用臨時表而強制轉換爲xml數據類型?

XML緩存存儲爲NText數據類型,我已經足夠好的解析了它的SQL XML庫。我的問題是 - 是否可以將多個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 2011-01-27 09:41:54

回答

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與臨時表不能被預編譯,但那些表變量可以是
  • ,但如果有大量的行,臨時表會快很多,因爲你可以索引他們
相關問題