1

SQL Server 2008 から xml を作成しました。現在の xml は、「FOR XML AUTO」を使用して生成されます。

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

しかし、次のような出力が必要です

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

したがって、基本的には、親要素の属性をサブ要素に変換したいと考えています。そして、追加のカスタマイズ要素が必要です。私を助けてください。

前もって感謝します。

4

3 に答える 3

3

FOR XML PATHSQL Server 2005 で導入されたオプションを確認する必要があります。詳細については、Microsoft SQL Server 2005 の FOR XML の新機能に関するドキュメントを参照してください。

基本的に、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')
于 2012-04-30T04:57:06.237 に答える
0

これはより詳細なFOR XML EXPLICITタイプです

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これはsql2000でも機能します。

于 2012-04-30T11:11:02.777 に答える
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')
于 2012-04-30T05:22:59.737 に答える