如何生成SQL查询以形成XML输出

时间:2015-05-26 06:11:37

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

我正在尝试生成如下的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

2 个答案:

答案 0 :(得分:2)

以下是答案:

;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>

希望这有帮助。

答案 1 :(得分:0)

使用此类查询:

;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>