2012-04-30 64 views
1

我已经从使用 “FOR XML AUTO”自定义XML和SQL Server

<Customer Name="john" City="Mumbai"> 
    <Project Project_Name="pqr" /> 
</Customer> 
<Customer Name="Rocky" City="Delhi"> 
    <Project Project_Name="abc" /> 
    <Project Project_Name="lmn" /> 
</Customer> 

产生2008 我当前XML的SQL Server中创建XML,但我希望输出像

<Customer > 
    <name>John</name> 
    <city>Mumbai</city> 
    <Projects> 
     <project> 
     <Project_Name>pqr</Project_Name> 
     </project> 
    </Projects> 
</Customer> 
<Customer > 
    <name>Rocky</name> 
    <city>Delhi</city> 
    <Projects> 
     <project> 
     <Project_Name>abc</Project_Name> 
     <Project_Name>lmn</Project_Name> 
     </project> 
    </Projects> 
</Customer> 

所以基本上我想将父元素的属性转换为子元素。并想要额外的自定义元素。请帮帮我。

在此先感谢。

回答

3

您需要查看SQL Server 2005引入的FOR XML PATH选项 - 请参阅What's New in FOR XML in Microsoft SQL Server 2005文档以获取更多信息。

基本上,与FOR XML PATH,你可以很容易地定义你的XML的形状。您可以定义某些结构,您可以定义某些列作为属性输出,其他列作为元素 - 完全在您的控制之下。

不知道你的表结构,我只能猜测一下表和列被称为你的情况 - 但你也许可以写类似:

SELECT 
    c.ID AS '@ID', -- define output as attribute on node 
    c.Name, -- if you don't specify anything -> output as element of the same name 
    c.City, 
    (SELECT 
     p.Name as 'Project_Name', -- define different XML element name for column 
     p.DueDate 
    FROM 
     dbo.Project p 
    WHERE 
     p.CustomerID = c.ID 
    FOR XML PATH('Project'), TYPE 
    ) AS 'Projects' 
FROM 
    dbo.Customer c 
FOR XML PATH('Customer'), ROOT('AllCustomers') 
0

我已经根据你的XML重建的行集,并使用FOR XML PATH您可以构建您的XML,只要你喜欢(给予好评的marc_s):

DECLARE @x XML = ' 
<Customer Name="john" City="Mumbai"> 
    <Project Project_Name="pqr" /> 
</Customer> 
<Customer Name="Rocky" City="Delhi"> 
    <Project Project_Name="abc" /> 
    <Project Project_Name="lmn" /> 
</Customer> 
' 

SELECT 
    c.Name AS 'name' 
    , c.City AS 'city' 
    , (SELECT 
     p.Project_Name AS 'Project_Name' 
    FROM (
    SELECT c.value('../@Name', 'VARCHAR(50)') AS CustomerName 
    , c.value('./@Project_Name', 'VARCHAR(50)') AS Project_Name 
    FROM @x.nodes('//Project') AS t(c) 
    ) p WHERE c.Name = p.CustomerName 
    FOR XML PATH('project'), TYPE) AS 'Projects' 
FROM 
(
SELECT c.value('./@Name', 'VARCHAR(50)') AS Name 
    , c.value('./@City', 'VARCHAR(50)') AS City 
FROM @x.nodes('//Customer') AS t(c) 
) c 
FOR XML PATH('Customer') 
0

这是更详细的​​型

CREATE TABLE #Customers (
      ID    INT 
      , Name   VARCHAR(100) 
      , City   VARCHAR(100) 
      ) 
CREATE TABLE #Projects (
      ID    INT 
      , Name   VARCHAR(100) 
      , Customer_ID INT 
      ) 

INSERT  #Customers 
SELECT  1, 'john', 'Mumbai' UNION ALL 
SELECT  2, 'Rocky', 'Delhi' UNION ALL 
SELECT  3, 'Stan', 'New York' --UNION ALL 

INSERT  #Projects 
SELECT  1, 'pqr', 1 UNION ALL 
SELECT  2, 'abc', 2 UNION ALL 
SELECT  3, 'lmn', 2 

SELECT  h.Tag 
      , h.Parent 
      , NULL   AS [Customer!1] 
      , c.Name  AS [Name!1000] 
      , c.City  AS [City!2000] 
      , NULL   AS [Projects!3000] 
      , NULL   AS [Project!3100] 
      , p.Name  AS [Project_Name!3110] 
FROM  (
      SELECT  NULL, 1 UNION ALL 
      SELECT   1, 1000 UNION ALL 
      SELECT   1, 2000 UNION ALL 
      SELECT   1, 3000 UNION ALL 
      SELECT    3000, 3100 UNION ALL 
      SELECT     3100, 3110 --UNION ALL 
      ) h(Parent, Tag) 
LEFT JOIN (
      SELECT  1     AS FirstTag 
         , 3000    AS LastTag 
         , c.* 
      FROM  #Customers c 
      ) c 
ON   h.Tag BETWEEN c.FirstTag AND c.LastTag 
LEFT JOIN (
      SELECT  3100    AS FirstTag 
         , 3110    AS LastTag 
         , c.Name   AS CustomerName 
         , p.Name 
      FROM  #Customers c 
      JOIN  #Projects p 
      ON   c.ID = p.Customer_ID 
      ) p 
ON   h.Tag BETWEEN p.FirstTag AND p.LastTag 
ORDER BY COALESCE(p.CustomerName, c.Name), p.Name, h.Tag 
FOR XML EXPLICIT 

DROP TABLE #Customers, #Projects 

生成此

<Customer> 
    <Name>john</Name> 
    <City>Mumbai</City> 
    <Projects> 
    <Project> 
     <Project_Name>pqr</Project_Name> 
    </Project> 
    </Projects> 
</Customer> 
<Customer> 
    <Name>Rocky</Name> 
    <City>Delhi</City> 
    <Projects> 
    <Project> 
     <Project_Name>abc</Project_Name> 
    </Project> 
    <Project> 
     <Project_Name>lmn</Project_Name> 
    </Project> 
    </Projects> 
</Customer> 
<Customer> 
    <Name>Stan</Name> 
    <City>New York</City> 
    <Projects /> 
</Customer> 

注意这不同于您的原始请求:Projects下有独立的Project s表示包项目名称。这也适用于sql2000。