【问题标题】:How do I generate an SQL Query to form XML output如何生成 SQL 查询以形成 XML 输出
【发布时间】:2015-05-26 06:11:37
【问题描述】:

我正在尝试生成如下 XML 输出:

<Employees>
    <EmployeeID>0025907E9BB4</EmployeeID>
    <EmpDateJoin>2015-05-18 01:58:44</EmpDateJoin>
    <EmpRegId>89-16036-1267</EmpRegId>
    <ProjectDetails> 
            Project Name: SVS-DC1 | Project Last Deployed: 2012-03-20 01:48:43 | ErrorDesc: Not Applicable
    </ProjectDetails>
    <ProjectDetails>
        Project Name: ADP-SERVER | Project Last Deployed: 2015-05-18 01:57:43 | ErrorDesc: backup failed due to low memory
    </ProjectDetails>
 </Employees>

但我的 SQL 输出是多个表的 JOINS,它们返回输出为

EmployeeID      EmpDateJoin             EmpRegId        ProjectName         LastDeployedDate    ErrorDesc
0025907E9BB4    2015-05-18 01:58:44     89-16036-1267   SVS-DC1             2012-03-20 01:48:43 Not Applicable
0025907E9BB4    2015-05-21 01:48:44     89-16036-1267   ADP-SERVER          2015-05-18 01:57:43 backup failed due to low memory

只想知道如何区分父标签中的不同值和项目详细信息标签中的资源值

我尝试过实现这一点,但只能在以下输出中生成:

 <Employees>
     <ProjectDetails>
        EmployeeID: 0025907E9BB4 | EmpDateJoin: 2015-05-18 01:58:44 | EmpRegId: 89-16036-1267 | Project Name: SVS-DC1 | Project Last Deployed: 2012-03-20 01:48:43 | ErrorDesc: Not Applicable
    </ProjectDetails>
     <ProjectDetails>
        EmployeeID: 0025907E9BB4 | EmpDateJoin: 2015-05-21 01:48:44 | EmpRegId: 89-16036-1267 | Project Name: ADP-SERVER | Project Last Deployed: 2015-05-18 01:57:43 | ErrorDesc: backup failed due to low memory
    </ProjectDetails>
 </Employees>

用于实现所需输出的 ​​SQL 查询:

DECLARE @XML VARCHAR(MAX)  
 SET @XML =
                (
                SELECT 'EmployeeID: ' + [EmpNo] , ' | EmpDateJoin: ' +  convert(nvarchar(MAX),[EmpDateJoin], 120), ' | EmpRegId: ' + [EmpRegId], 
                ' | Project Name: '+[ProjectName],  ' | Project Last Deployed: ' + convert(nvarchar(MAX), [LastDepDate], 120),  ' | ErrorDesc: ' + [ErrorDesc]                  FROM 
                FROM 
                    (
                    SELECT EmpNo, ProjectName,EmpDateJoin,EmpRegId, LastDepDate, ErrorDesc
                    FROM 
                    (
                        SELECT DAT.EmpNo AS EmpNo, RMC.ProjectName AS ProjectName, 
                        AL.[EmpDateJoin] AS [EmpDateJoin],DAT.[EmpRegId] AS [EmpRegId],
                        AL.[LastDepDate] as [LastDepDate], AL.ErrDescratDevice AS ErrorDesc,
                        CASE 
                            WHEN 
                            (CONS.ParentRegId IS NULL AND dbo.USF_Vault_ER_BackupPerDay(AGT.AgentID,Appliancedt) > 10 AND P.AgentUniqueID IS NOT NULL)  
                            OR
                            (AL.LastBckStatus <> 'SUCCESS' AND CONS.ParentRegId IS NULL AND dbo.USF_Vault_ER_BackupPerDay(AGT.AgentID,AD.Appliancedt) < 11)
                            OR
                            ((dbo.USF_AgentFailureBackupCount(AGT.AgentID) % 2 = 0 AND dbo.USF_AgentFailureBackupCount(AGT.AgentID) > 2 AND dbo.USF_Vault_ER_BackupPerDay(AGT.AgentID,AD.Appliancedt) > 10)
                                OR
                            (AL.LastBckStatus <> 'SUCCESS' AND dbo.USF_Vault_ER_BackupPerDay(AGT.AgentID,AD.Appliancedt) < 11))
                                AND DATEDIFF(MI,'01/01/1900',LBS.AppliancedateTime) > DATEDIFF(MI,'01/01/1900',CONS.RefDatetime) AND CONS.ParentRegId IS NOT NULL 
                        THEN 'E'      
                        ELSE 'G' END AS ProcessStatus
                        FROM Employees DAT WITH(NOLOCK) 
                        INNER JOIN EmployeeRefDep AGT WITH(NOLOCK) ON DAT.OrderID = AGT.OrderID AND AGT.[Status] = 'success'
                        INNER JOIN MstSKU MK  WITH(NOLOCK) ON AGT.ModelID=MK.ModelID AND SKUType = @SkuType
                        INNER JOIN EmpReg RM WITH(NOLOCK) ON DAT.Regid = RM.RegId AND RM.RegId = @InRegid 
                        INNER JOIN EmpReg RMC WITH(NOLOCK) ON AGT.Regid = RMC.RegId 
                        INNER JOIN MstMember MM WITH(NOLOCK) ON RM.MemberID = MM.MemberId AND MM.MemberId = @InMemberId
                        INNER JOIN MstSite MS WITH(NOLOCK) ON RM.SiteId = MS.SiteId AND MS.SiteId = @InSiteid
                        INNER JOIN ProjectLookup AL WITH(NOLOCK) ON AL.AgentUniqueID = AGT.AgentID
                    ) A 
                WHERE ProcessStatus <> 'G'
            )ProtectedMachine
        FOR XML PATH ('ProjectDetails'), ROOT('Employees') 
        )   
        SELECT @XML AS EventDetails

【问题讨论】:

  • 这是我会在表示层而不是 t-sql 中做的事情。
  • @ZoharPeled - 谢谢,但我的 Presentation 层在多个位置使用,我只需要这个字符串输出,它将自动以适当的格式显示。
  • 你能显示你目前得到的查询吗?
  • @Murtaza 请发布查询以获取当前输出
  • @ZoharPeled - 我已经用查询更新了问题

标签: sql sql-server xml sql-server-2005


【解决方案1】:

答案如下:

;WITH Employees AS (
    /*Your query here*/
)

SELECT 
    EmployeeID, 
    MIN(EmpDateJoin) AS 'EmpDateJoin', 
    EmpRegId, 
    CAST(STUFF((    SELECT 
                        ProjectName, 
                        LastDeployedDate, 
                        ErrorDesc 
                    FROM Employees E2 
                    WHERE E1.EmployeeID = E2.EmployeeID 
                          AND E1.EmpRegId = E2.EmpRegId 
                    FOR XML PATH('ProjectDetails')
                ), 1, 0, '') AS XML)
FROM Employees E1
GROUP BY EmployeeID, EmpRegId
FOR XML PATH('Employee'), ROOT('Employees'), TYPE

这是输出:

<Employees>
  <Employee>
    <EmployeeID>0025907E9BB4 </EmployeeID>
    <EmpDateJoin>2015-05-18T01:58:44</EmpDateJoin>
    <EmpRegId>89-16036-1267</EmpRegId>
    <ProjectDetails>
      <ProjectName>SVS-DC1</ProjectName>
      <LastDeployedDate>2012-03-20T01:48:43</LastDeployedDate>
      <ErrorDesc>Not Applicable</ErrorDesc>
    </ProjectDetails>
    <ProjectDetails>
      <ProjectName>ADP-SERVER</ProjectName>
      <LastDeployedDate>2015-05-18T01:57:43</LastDeployedDate>
      <ErrorDesc>backup failed due to low memory</ErrorDesc>
    </ProjectDetails>
  </Employee>
</Employees>

希望这会有所帮助。

【讨论】:

  • @Murtaza,我认为这是一个很好的答案,我认为您应该将其标记为答案。
【解决方案2】:

使用这种类型的查询:

;WITH t AS(
     /*Add your query here*/
)
SELECT @XML = CAST( '<Employees>' +
    (SELECT 
        t.EmployeeID,
        MIN(t.EmpDateJoin) AS EmpDateJoin,
        t.EmpRegId
    FROM t
    GROUP BY 
        t.EmployeeID,
        t.EmpRegId
    FOR XML PATH(''))
    +
    (SELECT 
        'Project Name : ' + ProjectName + '| Project Last Deployed: ' + LastDeployedDate + '|  ErrorDesc: ' + ErrorDesc AS ProjectDetails
    FROM 
        t Employees
    FOR XML PATH (''))
    +
    '</Employees>' AS xml)

为此:

<Employees>
  <EmployeeID>0025907E9BB4</EmployeeID>
  <EmpDateJoin>2015-05-18 01:58:44</EmpDateJoin>
  <EmpRegId>89-16036-1267</EmpRegId>
  <ProjectDetails>Project Name : SVS-DC1| Project Last Deployed: 2012-03-20 01:48:43|  ErrorDesc: Not Applicable</ProjectDetails>
  <ProjectDetails>Project Name : ADP-SERVER| Project Last Deployed: 2015-05-18 01:57:43|  ErrorDesc: backup failed due to low memory</ProjectDetails>
</Employees>

【讨论】:

  • 感谢您的努力。但是,在我正在编码的情况下,两次列出数据是不可行的,因此不能使用上面的示例。
  • @Murtaza 你可以使用WITH 语句来避免两次使用它;)。
  • 在一个员工有多个项目的情况下不起作用。您的查询将所有内容都弄乱了。
  • @dyatchenko 我查询了 OP 的输出;)。
猜你喜欢
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
相关资源
最近更新 更多