2015-09-23 5 views
2

Вот моя проблема с генерацией xml с требуемым форматом (у меня есть дублированные узлы): У меня есть модификация сущности записи, которая может быть сделана по нескольким столбцам за раз. Например, у меня есть следующие @my_table (мы можем видеть, что «MODIF 3» на «объекта 2» изменены 2 колонки в то же время, столбцы 5 и 6):дублированные узлы при генерации xml

| id_entity | id_modif | id_column | new_value | 
-------------------------------------------------  
| entity 1 | modif 1 | column 4 | coucou |  
| entity 2 | modif 2 | column 1 | papa  |  
| entity 2 | modif 3 | column 5 | blabla |  
| entity 2 | modif 3 | column 6 | toto  |  

Я должен написать XML select, который возвращает все изменения одного из объектов. Ожидаемый формат XML является следующее:

<history> 
    <id_entity></id_entity> 
    <modifs> 
    <modif> 
     <id_modif></id_modif> 
     <details> 
     <column></column> 
     <value></value> 
     </details> 
     <details></details> 
     <details></details> 
     ... 
    </modif> 
    <modif></modif> 
    <modif></modif> 
    .... 
    </modifs> 
</history> 

пример с @Entity = 'субъект 1':

<history> 
    <id_entity>entity 1</id_entity> 
    <modifs> 
    <modif> 
     <id_modif>modif 1</id_modif> 
     <details> 
     <column>column 4</columns> 
     <value>coucou</value> 
     </details> 
    </modif> 
    </modifs> 
</history> 

пример с @Entity = 'субъект 2':

<history> 
    <id_entity>entity 2</id_entity> 
    <modifs> 
    <modif> 
     <id_modif>modif 2</id_modif> 
     <details> 
     <column>column 1</column> 
     <value>papa</value> 
     </details> 
    </modif> 
    <modif> 
     <id_modif>modif 3</id_modif> 
     <details> 
     <column>column 5</column> 
     <value>blabla</value> 
     </details> 
     <details> 
     <column>column 6</column> 
     <value>toto</value> 
     </details> 
    </modif> 
    </modifs> 
</history> 

С выбор, который я написал (см. код в конце сообщения), проблема возникает, когда модификация изменяет несколько столбцов: поскольку в моей таблице есть многострочные строки для одного и того же modif_id, результатом в xml является дублирование проблемы ed node:

-- What I Got ('modif 3' node is duplicated because in @my_table I have 2 rows with 'modif 3') : 
<history> 
    <id_entity>entity 2</id_entity> 
    <modifs> 
    <modif> 
     <id_modif>modif 2</id_modif> 
     <details column 1 /> 
    </modif> 
    <modif> 
     <id_modif>modif 3</id_modif> 
     <details columns 5 /> 
     <details columns 6 /> 
    </modif> 
    <modif> 
     <id_modif>modif 3</id_modif> 
     <details columns 5 /> 
     <details columns 6 /> 
    </modif> 
    </modifs> 
</history> 

-- What I wanted (only one node 'modif 3' with 2 'details' nodes): 
<history> 
    <id_entity>entity 2</id_entity> 
    <modifs> 
    <modif> 
     <id_modif>modif 2</id_modif> 
     <details column 1 /> 
    </modif> 
    <modif> 
     <id_modif>modif 3</id_modif> 
     <details columns 5 /> 
     <details columns 6 /> 
    </modif> 
    </modifs> 
</history> 

Я попытался добавить «отдельный» в избранном статусе, но он не принят. Вот полный исполняемым код, если вы хотите играть ...:

declare @my_table table(
    id_entity varchar(10), 
    id_modif varchar(10), 
    id_column varchar(15), 
    new_value varchar(15)) 
insert into @my_table 
    select 'entity 1', 'modif 1', 'column 4', 'coucou' union 
    select 'entity 2', 'modif 2', 'column 1', 'papa' union 
    select 'entity 2', 'modif 3', 'column 5', 'blabla' union 
    select 'entity 2', 'modif 3', 'column 6', 'toto' 

declare @id_entity varchar(10) = 'entity 2' 

select 
    @id_entity as 'id_entity', 
    (select 
     parent.id_modif as 'id_modif', 
     (select distinct   
      child.id_column as 'column', 
      child.new_value as 'value' 
     from @my_table child 
     where child.id_entity = @id_entity 
     and child.id_modif = parent.id_modif 
     for xml path ('details'), type) '*' 
    from @my_table parent 
    where parent.id_entity = @id_entity 
    for xml path ('modif'), root('modifs'), type) '*' 
    for xml path ('history'), type 

Примечание: Я нашел обходной путь я показать свой босс с различной структурой XML, но это конец долгого процесса которые были бы слишком длинными для изменения ....

Большое спасибо!

ответ

2

Try gouping:

SELECT 
    t.id_entity, 
    (
     SELECT 
      p.id_modif, 
      (
       SELECT 
        h.id_column, 
        h.new_value 
       FROM @my_table h 
       WHERE p.id_modif = h.id_modif 
       FOR XML PATH('details'), TYPE 
      ) 
     FROM @my_table AS p 
     WHERE t.id_entity = p.id_entity 
     GROUP BY p.id_modif 
     FOR XML PATH('modif'), TYPE 
    ) AS modifs 
FROM @my_table AS t 
WHERE t.id_entity = @id_entity 
GROUP BY t.id_entity 
FOR XML PATH('history'), type 
+0

отлично! большое спасибо –

Смежные вопросы