从SQL Server存储过程返回XML

时间:2016-07-01 01:59:09

标签: sql-server xml tsql nested for-xml-path

我想以这种格式从SQL查询生成XML:

<Reports>
    <Header>
        <PrintedBy>XYZ </PrintedBy>
        <PrintedDate>22/01/2015</PrintedDate>
        <Image>C:/Img/a.png</Image>
        <Title>Title</Title>
    </Header>
    <Report>
        <Name>123</Name>
        <UserName></UserName>
        <Remarks></Remarks>
        <IPAddress>0.0.0.0</IPAddress>
        <DateCreated>2016-02-24T18:32:11.803</DateCreated>
        <AppID>BOS</AppID>
        <AppVersion>0.0.3.0</AppVersion>
        <LastLoggedin>2016-06-23T16:04:07.167</LastLoggedin>
    </Report>
    <Report>
        <Name>123</Name>
        <UserName></UserName>
        <Remarks></Remarks>
        <IPAddress>0.0.0.0</IPAddress>
        <DateCreated>2016-02-25T10:22:34.623</DateCreated>
        <AppID>BOS</AppID>
        <AppVersion>0.0.3.0</AppVersion>
        <LastLoggedin>2016-06-23T16:04:07.167</LastLoggedin>
    </Report>
</Reports>

标题行只能打印一次,不应重复每个报告行。

1 个答案:

答案 0 :(得分:0)

对于下一个问题,请提供表格结构和样本数据......

在这个答案中,我使用表变量来提供标题的数据。

并且 - 由于我不愿意输入您的数据 - 我读取您的XML 进入临时表并使用此临时表创建您的选择。最终SELECT是您需要的。你必须根据自己的需要调整它......

注意

标题中的日期时间格式是特定于文化的!避免这样做。如果不是1月22日,而是1月9日,那么一个月不知道是什么月份。在XML中,它在大多数情况下是ISO 8601。

DECLARE @headerTbl TABLE(PrintedBy VARCHAR(100),PritnedDate DATETIME,[Image] VARCHAR(100),Title VARCHAR(100));
INSERT INTO @headerTbl VALUES('XYZ',{d'2015-01-22'},'C:/Img/a.png','Title');

DECLARE @xml XML=
'<Reports>
    <Header>
        <PrintedBy>XYZ </PrintedBy>
        <PrintedDate>2015-01-22</PrintedDate>
        <Image>C:/Img/a.png</Image>
        <Title>Title</Title>
    </Header>
    <Report>
        <Name>123</Name>
        <UserName></UserName>
        <Remarks></Remarks>
        <IPAddress>0.0.0.0</IPAddress>
        <DateCreated>2016-02-24T18:32:11.803</DateCreated>
        <AppID>BOS</AppID>
        <AppVersion>0.0.3.0</AppVersion>
        <LastLoggedin>2016-06-23T16:04:07.167</LastLoggedin>
    </Report>
    <Report>
        <Name>123</Name>
        <UserName></UserName>
        <Remarks></Remarks>
        <IPAddress>0.0.0.0</IPAddress>
        <DateCreated>2016-02-25T10:22:34.623</DateCreated>
        <AppID>BOS</AppID>
        <AppVersion>0.0.3.0</AppVersion>
        <LastLoggedin>2016-06-23T16:04:07.167</LastLoggedin>
    </Report>
</Reports>';

SELECT Rep.value('Name[1]','varchar(max)') AS Name
      ,Rep.value('UserName[1]','varchar(max)') AS UserName
      ,Rep.value('Remarks[1]','varchar(max)') AS Remarks
      ,Rep.value('IPAddress[1]','varchar(max)') AS IPAddress
      ,Rep.value('DateCreated[1]','datetime') AS DateCreated
      ,Rep.value('AppID[1]','varchar(max)') AS AppID
      ,Rep.value('AppVersion[1]','varchar(max)') AS AppVersion
      ,Rep.value('LastLoggedin[1]','datetime') AS LastLoggedin
INTO #tmpYourTable
FROM @XML.nodes('/Reports/Report') AS One(Rep);

SELECT (
         SELECT *
         FROM @headerTbl
         FOR XML PATH('Header'),TYPE
       )
       ,(
         SELECT *
         FROM #tmpYourTable
         FOR XML PATH('Report'),TYPE
       )
FOR XML PATH('Reports')

GO
DROP TABLE #tmpYourTable