从表中生成嵌套的 xml;什么方法是最好的路径、元素?

问题描述 投票:0回答:1

我需要从我的表中生成如下格式的 XML。你能建议我应该使用什么方法(路径、元素、原始)或者可以是几种方法的组合吗?

请在下面找到我的测试数据和我刚刚开始的一些代码。另请参阅具有大量嵌套的请求的 XML 格式。这可以在一个

SELECT
中完成吗?或者我可以按级别组合多个部分吗?

SELECT *  INTO #t FROM (
SELECT  2020 yy, 'Alpha' CompanyName, 
   'BossA'  FirstName_Owner, 'Smith'  LastName_Owner,  'John1' FirstName_Client , 'Dow1'  LasttName_Client,'Yes'  Active union
SELECT  2020 yy, 'Alpha' CompanyName, 
   'BossA'  FirstName_Owner, 'Smith'  LastName_Owner,  'Peter2' FirstName_Client  , 'Redd2'  LasttName_Client,'No'   Active UNION
SELECT  2020 yy, 'Alpha' CompanyName, 
 'BossyBB' FirstName_Owner, 'Green'  LastName_Owner, 'Mary' FirstName_Client ,  'Robbins3'  LasttName_Client,'Yes'  Active
)a  ---   SELECT TOP 100 * FROM #t           --    DROP TABLE IF EXISTS  #t


SELECT    yy,   CompanyName  
  --SELECT 
  -- FirstName_Owner,   LastName_Owner,   
  -- FirstName_Client , LasttName_Client,  Active  
FROM #t
FOR XML RAW('CompanyInfo') , ELEMENTS -- Path
--FOR XML RAW('Client'), ROOT ('Clients')  

我的测试数据请求以 XML 格式输出:

<GemReport> 
    <Version>2.0</Version> 
    <Company>  
        <CompanyInfo> 
                     <Year>2020</Year> 
                     <CompanyName>Alpha</CompanyName> 
            <Owners> 
                <Owner> 
                        <FirstName>John</FirstName> 
                        <LastName>Doe</LastName> 
                    <Clients> 
                        <Client> 
                             <FirstName>John1</FirstName> 
                             <LastName>Doe1</LastName> 
                             <Contract> 
                                <Active>Yes</Active> 
                             </Contract> 
                        </Client> 
                        <Client> 
                             <FirstName>Peter2</FirstName> 
                             <LastName>Redd2</LastName> 
                             <Contract> 
                                <Active>NO</Active> 
                             </Contract> 
                        </Client> 
                    </Clients> 
                </Owner> 
                <Owner> 
                        <FirstName>BossyBB</FirstName> 
                        <LastName>Green</LastName> 
                    <Clients> 
                        <Client> 
                             <FirstName>Mary</FirstName> 
                             <LastName>Robbins3</LastName> 
                             <Contract> 
                                <Active>Yes</Active> 
                             </Contract> 
                        </Client>               
                </Owners> 
        </CompanyInfo> 
    </Company> 
</GemReport>
sql-server xml t-sql sql-server-2019
1个回答
0
投票

由于您的设计是非规范化的,因此您将需要在此处使用一些 self

JOIN
,使用 CTE 来获取公司和公司所有者详细信息的
DISTINCT
值。然后,您可以使用子查询为每个层嵌套
FOR XML PATH
Owners
Clients
)。

最有可能获得具有更大数据集的高性能解决方案,实际上是修复您的设计并将其标准化;那么您不需要多次扫描同一个表,而是可以为公司、所有者和客户创建一个表,每个表都有相关的主/外键约束和索引。

USE Sandbox;
GO

SELECT *
INTO dbo.YourTable
FROM (SELECT 2020 AS yy,
             'Alpha' AS CompanyName,
             'BossA' AS FirstName_Owner,
             'Smith' AS LastName_Owner,
             'John1' AS FirstName_Client,
             'Dow1' AS LasttName_Client,
             'Yes' AS Active
      UNION --ALL? 
      SELECT 2020 AS yy,
             'Alpha' AS CompanyName,
             'BossA' AS FirstName_Owner,
             'Smith' AS LastName_Owner,
             'Peter2' AS FirstName_Client,
             'Redd2' AS LasttName_Client,
             'No' AS Active
      UNION --ALL? 
      SELECT 2020 AS yy,
             'Alpha' AS CompanyName,
             'BossyBB' AS FirstName_Owner,
             'Green' AS LastName_Owner,
             'Mary' AS FirstName_Client,
             'Robbins3' AS LasttName_Client,
             'Yes' AS Active) a;

GO
WITH Companies AS(
    SELECT DISTINCT
           CompanyName,
           yy
    FROM dbo.YourTable),
CompanyOwners AS(
    SELECT DISTINCT
           CompanyName,
           yy,
           FirstName_Owner,
           LastName_Owner
    FROM dbo.YourTable)
SELECT 2.0 AS Version,
       (SELECT C.yy AS [Year],
               C.CompanyName AS [CompanyName],
               (SELECT CO.FirstName_Owner AS FirstName,
                       CO.LastName_Owner AS LastName,
                       (SELECT YT.FirstName_Client AS FirstName,
                               YT.LasttName_Client AS LastName,
                               YT.Active AS [Contract/Active]
                        FROM dbo.YourTable YT
                        WHERE YT.yy = CO.yy
                          AND YT.CompanyName = CO.CompanyName
                          AND YT.FirstName_Owner = CO.FirstName_Owner --I hope this can't be NULL
                          AND YT.LastName_Owner = CO.LastName_Owner --I hope this can't be NULL
                        FOR XML PATH('Client'),ROOT('Clients'),TYPE)
                FROM CompanyOwners CO
                WHERE CO.yy = C.yy
                  AND CO.CompanyName = C.CompanyName
                FOR XML PATH('Owner'),ROOT('Owners'),TYPE)
        FROM Companies C
        FOR XML PATH('CompanyInfo'), ROOT('Company'),TYPE)
FOR XML PATH('GemReport')

GO
DROP TABLE dbo.YourTable;

生成以下 XML:

<GemReport>
  <Version>2.0</Version>
  <Company>
    <CompanyInfo>
      <Year>2020</Year>
      <CompanyName>Alpha</CompanyName>
      <Owners>
        <Owner>
          <FirstName>BossA</FirstName>
          <LastName>Smith</LastName>
          <Clients>
            <Client>
              <FirstName>John1</FirstName>
              <LastName>Dow1</LastName>
              <Contract>
                <Active>Yes</Active>
              </Contract>
            </Client>
            <Client>
              <FirstName>Peter2</FirstName>
              <LastName>Redd2</LastName>
              <Contract>
                <Active>No</Active>
              </Contract>
            </Client>
          </Clients>
        </Owner>
        <Owner>
          <FirstName>BossyBB</FirstName>
          <LastName>Green</LastName>
          <Clients>
            <Client>
              <FirstName>Mary</FirstName>
              <LastName>Robbins3</LastName>
              <Contract>
                <Active>Yes</Active>
              </Contract>
            </Client>
          </Clients>
        </Owner>
      </Owners>
    </CompanyInfo>
  </Company>
</GemReport>

注意,这与 OP 所需的 XML 不匹配,因为那不是有效的 XML。最后一个

Clients
Owner
节点not 关闭。我以为这是错误的。

© www.soinside.com 2019 - 2024. All rights reserved.