SQL - 在不使用临时表的情况下转换为xml数据类型?

时间:2011-01-27 09:00:36

标签: sql-server xml

我正在编写一些报告存储过程,需要在SQL 2008中解析一些XML。它适用于Umbraco CMS系统,它以一种不适合查询许多列的特殊方式存储其版本化数据。它还保留了所有已发布项的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>

提前致谢。

2 个答案:

答案 0 :(得分:2)

这是一份工作样本。只需将其作为子查询内联并执行双nvarchar-&gt; 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 :(得分:1)

切换到表格变量可以改善您的表现:

  • 表变量未记录(不参与交易)
  • 带有临时表的SP无法预编译,但具有表变量的SP可以
  • 但是,如果有大量行,临时表会快得多,因为你可以为它们编制索引