Вопрос

У меня есть следующий запрос

Select field1 as 'node1/field1',
       field2 as 'node1/field2',
  (Select field3 as 'child1/field3',
          field4 as 'child1/field4'
   From table2
   FOR XML PATH(''),TYPE,Elements)
From Table1 FOR XML PATH('Root'),Elements

Это производит:

<Root>
  <node1>
    <field1>data1</field1>
    <field2>data2</field2>
  </node1>
   <child1>
     <field3>data3</field3>
     <field4>data4</field4>
   </child1>
   <child1>
     ...   
</Root>

Я бы хотел, чтобы дочерние узлы 1 были частью узла 1, а не отдельным узлом ниже.

<Root>
  <node1>
    <field1>data1</field1>
    <field2>data2</field2>
    <child1>
       <field3>data3</field3>
       <field4>data4</field4>
    </child1>
    <child1>
      ...
 </node1>
 <node1>
   ...
</Root>

Я попытался поместить node1 в ПУТЬ к подзапросу

FOR XML PATH('node1'),TYPE,Elements)

или добавляя к именам полей подзапроса префикс node1

Select field3 as 'node1/child1/field3',

но оба создают новый элемент node1 для подзапроса.

Кто-нибудь знает, как я могу этого добиться?

Спасибо

Это было полезно?

Решение

Вы должны сообщить SQL Server, как связаны table1 и table2.Основываясь на вашем ответе ниже, я думаю, что что-то подобное могло бы сработать:

select 
    table1.field1 as 'Node1/Field1'
,   table2.field1 as 'Node1/Child1/Field1'
,   table1.field2 as 'Node2/Field2'
from table1
left join table2 on table1.id = table2.table1id
for xml PATH(''), ROOT('Root')

Это должно привести к созданию XML, подобного:

<Root>
    <Node1>
        <Field1>Value</Field1>
        <Child1>
            <Field1>Value</Field1>
        </Child1>
    </Node1>
    <Node2>
        <Field2>Value</Field2>
    </Node2>
</Root>

Другие советы

Я не проделал большой работы с T-SQL и для XML, но я решил аналогичную проблему, вызывая часть запроса FOR XML после каждого подзапроса, как показано ниже, и используя идентификатор ПУТИ для установки узлов:

SELECT field1 as "Field1",
    field2  as "Field2",
    (select
        field3 as "Field3",
        field4 as "Field4"

        from table2 t2 inner join 
        tlink tl on tl.id = t2.id inner join
        table2 on t2.id = tl.id
        group by field3, field4
        FOR XML PATH ('Child'), type
        ) 

from table2 t2 
group by field1, field2
FOR XML PATH('Node'), ROOT('Root')

это возвращает:

<Root>
  <Node1>
    <Field1>data1</Field1>
    <Field2>data2</Field2>
    <Child1>
      <Field3>data3</Field3>
      <Field4>data4</Field4>
    </Child1>
  </Node1>
  <Node2>
    <Field1>data1.2</Field1>
    <Field2>data2.2</Field2>
    <Child2>
      <Field3>data3.2</Field3>
      <Field4>data4.2</Field4>
    </Child2>

...
  </Node2>

...
</Root>

Как упоминал Андомар, вам необходимо убедиться, что ваши данные соединены правильно.

У меня также есть предложение Group By, чтобы убедиться, что данные не "сбиваются с пути".У меня возникла проблема с репликацией данных подзапроса как дочерних для каждой записи во внешнем запросе (под каждым узлом было несколько дочерних элементов, связанных с количеством имеющихся узлов).) Я уверен, что есть простое объяснение, но я работал в сжатые сроки, когда делал это, и никогда не возвращался, чтобы проверить...

Если это неправильное использование или кто-нибудь может пролить свет на повторяющиеся группы, пожалуйста, укажите на это, и я отредактирую...

Мой первый пример запроса был не совсем правильным, как вы указали.Вот более точный пример запроса.

Select field1 as 'node1/field1',       
       field2 as 'node1/field2',  
  (Select field3 as 'child1/field3',          
        field4 as 'child1/field4'   
   From table2   
   Where table1.ID = table2.ID
   FOR XML PATH(''),TYPE,Elements),
       field5 as 'node2/field5',
       field6 as 'node2/field6'
From table1 FOR XML PATH('Root'),Elements

Который производит:

<Root>
  <node1>
    <field1>data1</field1>
    <field2>data2</field2>
  </node1>   
  <child1>     
    <field3>data3</field3>
    <field4>data4</field4>
  </child1>
  <node2>
    <field5>data5</field5>
    <field6>data6</field6>
  </node2>
</Root>

field5 и field6 являются полями из внешнего запроса, но находятся в пределах другого пути к узлу, node2.Вот почему у меня не может быть PATH('node') во внешнем запросе.Внешние поля запроса используются во многих различных путях к узлам в корневом каталоге.Мне нужен подзапрос для повторной настройки под node1, и есть другие подзапросы, которые нужно вернуть под node2, node3...
Я очень надеюсь, что в моих словах есть смысл.Это мой первый пост, и в следующий раз я обязательно опубликую лучший пример запроса.

Спасибо за ответы.

Дирк

Возможно, будет иметь больше смысла, если вы опубликуете некоторые образцы данных, а не будете использовать node1, field1, child1 и т.д.и объясните, из каких таблиц поступают данные.

XML является иерархическим по своей природе.Вы не можете произвольно запускать новые узлы, которые не связаны с другими узлами под корнем, что, похоже, вы пытаетесь сделать.

Все , что внутри <node1>..чтобы..</node1> относится к одной записи и данным, сгенерированным ее подзапросами.Следующая последовательность узлов будет реплицировать структуру следующим образом <node2>..чтобы..</node2> для следующей записи.

Если вы хотите больше подзапросов под каждым узлом, то просто напишите каждый из них в SQL со своим собственным FOR XML PATH('SubNodeName')

Опубликуйте свой XSD или образец XML-кода, и я посмотрю, смогу ли я понять, что вы пытаетесь сделать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top