Добавить / изменить столбец XML с атрибутами из другого значения столбца, вернуть результаты в виде столбца с другими полями - PullRequest
0 голосов
/ 25 августа 2011

У меня есть столбец 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

Теперь мне нужно вернуть этот запрос вместе с другими столбцами. Попытка вложить это как подзапрос не работает. Я должен сделать его вложенным в другой 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 голосов
/ 26 августа 2011
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" />
...