2015-01-20 2 views
1

Я не привык использовать xml в столбце sql и задать вопрос об обновлении содержимого этого столбца.SQL XML column - обновление значения дочернего узла на основе других узлов

У меня есть таблица (TableXML) с колонной (ColumnXML), содержащий следующую иерархию XML: Xml/Content/Queues/list/Item/

Каждый элемент в /Name, список PluginsProperties/Item

и каждый из них другой элемент имеют /key и value

Например:

<Xml> 
    <Content Tr="1"> 
     <Queues Tr="12"> 
      <list Tr="13"> 
       <Item Tr="14"> 
        <Name Tr="2">Data Load Exception</Name> 
        <PluginProperties Tr="15"> 
         <Item Tr="16"> 
          <key Tr="2">MSMQQueueType</key> 
          <value Tr="2">PrivateQueue</value> 
         </Item> 
         ...........more items 
        </PluginProperties> 
       </Item> 
       ...........more items 
      </list> 
     </Queues> 
    </Content> 
</Xml> 

Что я хотел бы сделать:

Обновить значение /Xml/Content/Queues/list/Item/PluginProperties/Item/value тега PublicQueue

где /Xml/Content/Queues/list/Item/PluginProperties/Item/key является MSMQQueueType

и /Xml/Content/Queues/list/Item/Name является Data Load Exception

Нет "Queue пункт" кроме имени с именем Data Load Exception, должно быть затронуто, и никакой элемент «PluginProperties», отличный от ключа с MSMQQueueType, не должен влиять для него.

Спасибо! =)

ответ

1

вы можете использовать replace value of положение, чтобы сделать это

, если это был один узел, то это может быть сделано с использованием одной инструкции, как показано ниже

 update TableXML 
    set columnXML.modify(' 
      replace value of ((/Xml/Content/Queues/list/Item/PluginProperties/Item/value)[1]/text())[1] with ''PublicQueue''') 
where columnXML.value('((/Xml/Content/Queues/list/Item/PluginProperties/Item/key)[1]/text())[1]','varchar(50)') = 'MSMQQueueType' 
    and columnXML.value('((/Xml/Content/Queues/list/Item/Name)[1]/text())[1]','varchar(50)') = 'Data Load Exception' 

AS существует множество узлов, нам нужно чтобы получить счетчик узлов и сделать это, используя цикл, как показано ниже

declare @elements int 

select @elements = ISNULL(columnXML.value('count(/Xml/Content/Queues/list/Item/PluginProperties/Item)', 'int'),0) 
from TableXML 


while @elements > 0 
begin 

    update TableXML 
    set columnXML.modify 
    ('replace value of ((/Xml/Content/Queues/list/Item/PluginProperties/Item/value)[sql:variable("@elements")]/text())[1] 
     with ''PublicQueue''') 
    where columnXML.value('((/Xml/Content/Queues/list/Item/PluginProperties/Item/key)[sql:variable("@elements")]/text())[1]','varchar(50)') = 'MSMQQueueType' 
    and columnXML.value('((/Xml/Content/Queues/list/Item/Name)[sql:variable("@elements")]/text())[1]','varchar(50)') = 'Data Load Exception' 


    set @elements = @elements - 1 
end 
+0

Привет и спасибо! Разве нет возможности с SQL XML обновлять многие узлы с помощью одного оператора? (все узлы, соответствующие фильтру) – ibiza

+1

@ibiza, я не думаю, что есть массовое обновление для всех узлов XML – radar