使用其他列值中的属性添加/修改XML列,将结果作为列返回到其他字段

时间:2011-08-25 16:56:50

标签: sql xml sql-server-2008 xquery

我有一个XML列,我们称之为“XmlField”,如下所示:

<Node Attrib="9">Name1</Node>
<Node Attrib="100">Name2</Node>
<Node Attrib="101">Name2</Node>

示例:

    select
      (list of fields)
    from
      TableX , TableY         -- TableX has the XMLcolumn    
     CROSS APPLY TableX.XmlField.nodes('/Node') m1(xmlcol)
    where
    m1.xmlcol.value('@Attrib', 'int') = TableY.IntField        

问题: 我必须从'TableY'中检索不同的列/列集,并将其附加到返回的XML数据中,例如作为属性,满足上述条件。 我不需要将它存储在任何表中,仅用于检索 XmlField(或任何其他临时数据等)以查看更新:

 <Node Attrib="9" OtherField="SomeValue">Name1</Node>
 <Node Attrib="100" OtherField="SomeValue2">Name1</Node>

其中'OtherField'是'TableY'的列用于更新查询返回的'XmlField'(不存储在表本身中)

select
    TableY.IntField  as '@Attrib', 
    TableY.OtherField as '@OtherField'
        from
         TableY        ,  TableX 
         CROSS APPLY TableX.XmlField.nodes('/Node') m1(xmlcol)
        where
        m1.xmlcol.value('@Attrib', 'int') = TableY.IntField  
    FOR XML PATH('Node'), TYPE

现在我需要将此查询与其他列一起返回。 尝试将其嵌套为子查询不起作用。我必须将它嵌套在另一个XML blob中,该blob还将所有其他列作为XML返回。

这样的事情(删除变量集并尝试直接检索也不起作用)

DECLARE @result XML
SELECT @result = 
(SELECT (list of columns)
   , 
   (Select
    TableY.IntField  as '@Attrib', 
    TableY.OtherField as '@OtherField'
        from
         TableY        ,  TableX 
         CROSS APPLY TableX.XmlField.nodes('/Node') m1(xmlcol)
        where
        m1.xmlcol.value('@Attrib', 'int') = TableY.IntField  
    FOR XML PATH('Node'), TYPE) --AS 'XmlField'
, (some more columns)
FROM TableX
  -- Do some joins (this needs to be satisfied for subquery that builds up the updated XML'column')
  -- Check for some conditions
   FOR XML PATH('Root'), TYPE); 

我应该如何将此更新的属性作为另一列返回?我还需要确保子查询正确完成外部联接和条件检查,有没有办法确保这一点?

1 个答案:

答案 0 :(得分:0)

declare @TableX table (ID int identity, XmlField xml)

insert into @TableX values
(
'<Node Attrib="9">Name1</Node>
 <Node Attrib="100">Name2</Node>
 <Node Attrib="101">Name2</Node>'
)

insert into @TableX values
(
'<Node Attrib="9">Name1</Node>
 <Node Attrib="101">Name2</Node>'
)

insert into @TableX values
(
'<Node Attrib="1">Name1</Node>'
)

declare @TableY table (IntField int, OtherField varchar(15))

insert into @TableY values 
(9, 'SomeOtherValue1'),
(100, 'SomeOtherValue2'),
(101, 'SomeOtherValue3')

;with C as
(
  select X.ID,
         Y.IntField as Attrib,
         Y.OtherField as OtherField
  from @TableX as X
    cross apply X.XmlField.nodes('/Node') as T(N)
    inner join @TableY as Y
      on T.N.value('@Attrib', 'int') = Y.IntField
)
select (select C2.Attrib as '@Attrib',
               C2.OtherField as '@OtherField'
        from C as C2
        where C1.ID = C2.ID
        for xml path('Node'), type) as XMLField       
from C as C1
group by ID

结果:

XMLField
<Node Attrib="9" OtherField="SomeOtherValue1" /><Node Attrib="100" OtherField="SomeOtherValue2" /><Node Attrib="101" OtherField="SomeOtherValue3" />
<Node Attrib="9" OtherField="SomeOtherValue1" /><Node Attrib="101" OtherField="SomeOtherValue3" />