Изменить формат Xml с помощью FOR XML [SQL] - PullRequest
0 голосов
/ 28 февраля 2020

У меня возникла проблема при попытке создать экземпляр XML в SSMS. Я использую 3 представления для создания файла xml, вот код, который я написал:

    DECLARE @xmlDoc xml  
SET @xmlDoc = (
        SELECT *
        FROM   db.View1 AS v1
        INNER JOIN  db.View2 AS v2  ON v2.link = v1.link
        INNER JOIN db.View3 AS v3 ON v3.link = v1.link
        FOR XML AUTO)  
SELECT @xmlDoc

Что я получаю в этом формате:

<v1 field="data" ...>
    <v2 field="data" ...>
        <v3 field="data" .../>
    </v2>
</v1>

Но мне нужно, чтобы v2 и v3 были на одном уровне, как это:

<v1 field="data" ...>
    <v2 field="data" .../>
    <v3 field="data" .../>
</v1>

Если у кого-то есть идеи, это поможет меня много! Спасибо!

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Пока мы ждем вашего (1) DDL ...

Пожалуйста, попробуйте следующее в качестве концептуального примера.

Если у вас есть вложенные XML из разных таблиц, вам нужно объединить их с помощью предложения WHERE. он имитирует коррелированный подзапрос.

SQL

-- DDL and sample data population, start
DECLARE @tbl1 TABLE (ID INT PRIMARY KEY, [state] VARCHAR(20));
DECLARE @tbl2 TABLE (ID INT PRIMARY KEY, ParentID INT, [city] VARCHAR(20));
DECLARE @tbl3 TABLE (ID INT PRIMARY KEY, ParentID INT, [population] INT);

INSERT INTO @tbl1 (ID, state) 
VALUES ( 1, 'Florida');
INSERT INTO @tbl2 (ID, ParentID, city)
VALUES (10, 1, 'Miami'); 
INSERT INTO @tbl3 (ID, ParentID, population)
VALUES (5, 1, 470914);
-- DDL and sample data population, end

SELECT v1.state AS [field]
, (SELECT v2.city  AS [field]
    FROM @tbl2 AS v2
    WHERE v2.ParentID = v1.ID
    FOR XML AUTO, TYPE
    )
, (SELECT v3.population AS [field]
    FROM @tbl3 AS v3
    WHERE v3.ParentID = v1.ID
    FOR XML AUTO, TYPE
    )
FROM @tbl1 AS v1
FOR XML AUTO, TYPE;

Вывод

<v1 field="Florida">
  <v2 field="Miami" />
  <v3 field="470914" />
</v1>
0 голосов
/ 28 февраля 2020

В общем, я бы предложил использовать FOR XML PATH(). Этот режим обеспечивает максимальный контроль над тем, как будет выглядеть XML. Режим AUTO - по крайней мере, для - волхвов c: -)

Но вы можете попробовать это:

Создать макет для имитации вашего сценария (Пожалуйста, сделайте это самостоятельно в следующем вопросе):

DECLARE @t1 TABLE(ID1 INT IDENTITY,SomeValue VARCHAR(100));
INSERT INTO @t1 VALUES('test1'),('test2');

DECLARE @t2 TABLE(ID2 INT IDENTITY,linkT1 INT,SomeValue VARCHAR(100));
INSERT INTO @t2 VALUES(1,'test1.2.1'),(1,'test1.2.2'),(2,'test2.2.1');

DECLARE @t3 TABLE(ID3 INT IDENTITY,linkT1 INT,SomeValue VARCHAR(100));
INSERT INTO @t3 VALUES(1,'test1.3.1'),(1,'test1.3.2'),(2,'test2.3.1');

- Ваш запрос слегка изменен на коррелированные подзапросы :

DECLARE @xmlDoc xml  
SET @xmlDoc = (
        SELECT v1.*
              ,(SELECT * FROM @t2 AS vs2 WHERE vs2.linkT1=v1.ID1 FOR XML AUTO,TYPE)
              ,(SELECT * FROM @t3 AS vs3 WHERE vs3.linkT1=v1.ID1 FOR XML AUTO,TYPE)
        FROM  @t1 AS v1
        FOR XML AUTO)  
SELECT @xmlDoc;

Результат

<v1 ID1="1" SomeValue="test1">
  <vs2 ID2="1" linkT1="1" SomeValue="test1.2.1" />
  <vs2 ID2="2" linkT1="1" SomeValue="test1.2.2" />
  <vs3 ID3="1" linkT1="1" SomeValue="test1.3.1" />
  <vs3 ID3="2" linkT1="1" SomeValue="test1.3.2" />
</v1>
<v1 ID1="2" SomeValue="test2">
  <vs2 ID2="3" linkT1="2" SomeValue="test2.2.1" />
  <vs3 ID3="3" linkT1="2" SomeValue="test2.3.1" />
</v1>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...