2016-05-31 7 views
1

Ich habe eine SQL Server-Datenbank mit 3 Tabellen und ich muss eine XML-Datei mit hierarchischer Struktur aus diesen Tabellen erstellen.Erstellen Sie hierarchische XML aus SQL Server-Tabellen

Eine Tabelle enthält Produkte:

ProductID ProductLanguageID ProductDefaultShopID ProductNumber ProductName ProductPrice 
------------------------------------------------------------------------------------------ 
[email protected]@Inc LANG2    Inc     100101  ABC   159,61 
[email protected]@Inc LANG2    Inc     100102  BCD   159,61 
[email protected]@Inc LANG2    Inc     100105  FRE   159,61 
[email protected]@Inc LANG2    Inc     100106  GDE   159,61 

die zweite hat Gruppen

GroupID  GroupLanguageID GroupName   GroupNumber 
------------------------------------------------------------ 
[email protected]@Inc  LANG2    AAA    1 
[email protected]@Inc LANG2    BBB    1.01 
[email protected]@Inc LANG2    CCC    1.02 
[email protected]@Inc LANG2    DDD    1.03 
[email protected]@Inc LANG2    GGG    1.12 

die dritte Sprachen

LanguageID LanguageCode2 LanguageName 
---------------------------------------- 
LANG1  ES    Spain 
LANG2  EN    English 

Ich habe auch 2 Tabellen, die keine Verbindungen haben dont zu weitere Tabellen:

Tabelle

Gruppe Relations

GroupRelationsGroupID GroupRelationsParentID 
-------------------------------------------- 
[email protected]@Inc    [email protected]@Inc 
[email protected]@Inc    [email protected]@Inc 
[email protected]@Inc    [email protected]@Inc 
[email protected]@Inc    [email protected]@Inc 

Group Product Relation Tabelle

GroupProductRelationGroupID GroupProductRelationProductID 
------------------------------------------------------------- 
[email protected]@Inc      [email protected]@Inc 
[email protected]@Inc      [email protected]@Inc 
[email protected]@Inc      [email protected]@Inc 

Die XML-Ausgabe folgende Struktur haben sollte:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <productgroup1> 
    <groupname>AAA</groupname> 
    <productgroup2> 
     <groupname>BBB</groupname> 
     <productgroup3> 
     <groupname>CCC</groupname> 
     <products> 
      <product> 
      <itemName>ABC</itemName> 
      <itemNumber>100303</itemNumber> 
      <itemPrice>159.61</itemPrice> 
      <ExtraProductgroup> 
       <extraProductgroupName>GGG</extraProductgroupName> 
       <itemName>FRE</itemName> 
       <itemNumber>100305</itemNumber> 
       <itemPrice>159.61</itemPrice> 
      </ExtraProductgroup> 
      </product> 
     <product> 
      <itemName>BCD</itemName> 
      <itemNumber>100302</itemNumber> 
      <itemPrice>159.61</itemPrice> 
      </product> 
     </products> 
     </productgroup3> 
    </productgroup2> 
    </productgroup1> 
</root> 

Ich kann nur verwenden T-SQL und C# (ASP. Netz Web Forms). HILFE!!! :-)

+1

Ich sehe keine Möglichkeit, dass XML aus diesen Daten zu erhalten. Woher kommt beispielsweise itemColor? Was ist mit ExtraProduktgruppe? Wenn Sie möchten, dass jemand eine Chance hat, erstellen Sie mindestens die gewünschte Ausgabe von der gegebenen Eingabe von Hand. Ansonsten raten wir nur hier. –

+0

Sie haben eine ProductNumber und eine ProductID ist die Nummer mit '@@ Inc' - Was ist die * real * ID? Scheint seltsam ... Keiner von ihnen ist irgendwo in den anderen Daten zu finden. Wie ist ein Produkt an eine Gruppe gebunden? Die Gruppen scheinen hierarchisch geschachtelt zu sein. Gibt es eine maximale Tiefe? Gruppen- und Gruppenbeziehung halten IDs, die nicht in der Gruppentabelle gefunden werden können ... Sie müssen ** funktionierende Beispieldaten mit einer Beispielausgabe bereitstellen, die zu diesen Daten passt !! ** Bereiten Sie eine [MCVE] vor (http: // stackoverflow. com/help/mcve) (Code oder [Geige] (www.sqlfiddle.com) – Shnugo

Antwort

0

Ich muss zugeben, dass ich wirklich bezweifle, dass Sie mit dieser Struktur glücklich werden ... Warum sind Produkte unterhalb von groupLevel3, wenn sie mit einer level2-Gruppe verwandt sind? Warum befinden sich ABC und BCD auf demselben Niveau? Wie wird die ExtraGroup gefunden?

Diese Lösung löst nicht alle Daten generisch, bringt aber zumindest das gewünschte Ergebnis mit den gegebenen Daten zurück.

CREATE TABLE #Products(ProductID VARCHAR(50),ProductLanguageID VARCHAR(50),ProductNumber INT, ProductName VARCHAR(50), ProductPrice DECIMAL(14,4)); 
INSERT INTO #Products VALUES 
('[email protected]@Inc','LANG2',100101,'ABC',159.61) 
,('[email protected]@Inc','LANG2',100102,'BCD',159.61) 
,('[email protected]@Inc','LANG2',100105,'FRE',159.61) 
,('[email protected]@Inc','LANG2',100106,'GDE',159.61) 
; 

CREATE TABLE #Groups(GroupID VARCHAR(50),GroupLanguageID VARCHAR(50),GroupName VARCHAR(50),GroupNumber DECIMAL(5,2)); 
INSERT INTO #Groups VALUES 
('[email protected]@Inc','LANG2','AAA',1) 
,('[email protected]@Inc','LANG2','BBB',1.01) 
,('[email protected]@Inc','LANG2','CCC',1.02) 
,('[email protected]@Inc','LANG2','DDD',1.03) 
,('[email protected]@Inc','LANG2','GGG',1.12) 
; 

CREATE TABLE #Languages(LanguageID VARCHAR(50),LanguageCode2 VARCHAR(50),LanguageName VARCHAR(50)); 
INSERT INTO #Languages VALUES 
('LANG1','ES','Spain') 
,('LANG2','EN','English'); 

CREATE TABLE #GroupRelations(GroupRelationsGroupID VARCHAR(50),GroupRelationsParentID VARCHAR(50)); 
INSERT INTO #GroupRelations VALUES 
('[email protected]@Inc','[email protected]@Inc') 
,('[email protected]@Inc','[email protected]@Inc') 
,('[email protected]@Inc','[email protected]@Inc') 
,('[email protected]@Inc','[email protected]@Inc'); 

CREATE TABLE #GroupProductRelations(GroupProductRelationGroupID VARCHAR(50),GroupProductRelationProductID VARCHAR(50)); 
INSERT INTO #GroupProductRelations VALUES 
('[email protected]@Inc','[email protected]@Inc') 
,('[email protected]@Inc','[email protected]@Inc') 
,('[email protected]@Inc','[email protected]@Inc'); 


GO 

WITH TopGroups AS 
(
    SELECT gr.GroupID 
    FROM #Groups AS gr 
    WHERE NOT EXISTS(SELECT 1 FROM #GroupRelations AS x WHERE gr.GroupID = x.GroupRelationsGroupID) 
) 
,recGroup AS 
(
    SELECT 1 AS GroupLevel 
      ,g.GroupID 
      ,g.GroupLanguageID 
      ,g.GroupName 
      ,g.GroupNumber 
      ,gr.GroupRelationsParentID AS ParentGroupID 
    FROM #Groups AS g 
    LEFT JOIN #GroupRelations AS gr ON g.GroupID=gr.GroupRelationsGroupID 
    WHERE gr.GroupRelationsParentID IS NULL 
    UNION ALL 
    SELECT prev.GroupLevel + 1 
      ,gNext.GroupID 
      ,gNext.GroupLanguageID 
      ,gNext.GroupName 
      ,gNext.GroupNumber 
      ,grNext.GroupRelationsParentID 
    FROM #GroupRelations AS grNext 
     INNER JOIN #Groups AS gNext ON grNext.GroupRelationsGroupID=gNext.GroupID 
     INNER JOIN recGroup AS prev ON grNext.GroupRelationsParentID=prev.GroupID 
) 
SELECT * 
INTO #tmpFullResult 
FROM recGroup 
LEFT JOIN #GroupProductRelations AS gp ON recGroup.GroupID=gp.GroupProductRelationGroupID 
LEFT JOIN #Products AS p ON gp.GroupProductRelationProductID=p.ProductID 
LEFT JOIN #Languages AS l ON p.ProductLanguageID=l.LanguageID; 

SELECT * FROM #tmpFullResult; 

SELECT lvl1.GroupName AS groupName 
     ,(  
     SELECT lvl2.GroupName AS groupName 
       ,(
       SELECT lvl3.GroupName AS groupName 
        ,(
         SELECT prod.ProductName AS itemName 
           ,prod.ProductNumber AS itemNumber 
           ,prod.ProductPrice AS itemPrice 
           ,(
            SELECT prodExtra.GroupName AS extraProductGroupName 
              ,prodExtra.ProductName AS itemName 
              ,prodExtra.ProductNumber AS itemNumber 
              ,prodExtra.ProductPrice AS itemPrice 
            FROM #tmpFullResult AS prodExtra 
            WHERE prodExtra.ProductID IS NOT NULL 
             AND prodExtra.GroupLevel=5 
            FOR XML PATH('ExtraProductgroup'),TYPE 
           ) 
         FROM #tmpFullResult AS prod 
         WHERE prod.ProductID IS NOT NULL 
          AND prod.GroupLevel<5 
         FOR XML PATH('product'),ROOT('products'),TYPE 
        ) 
       FROM #tmpFullResult AS lvl3 
       WHERE lvl3.GroupLevel=3 AND lvl3.ParentGroupID=lvl2.GroupID 
       FOR XML PATH('productGroup3'),TYPE 
       ) 
     FROM #tmpFullResult AS lvl2 
     WHERE lvl2.GroupLevel=2 AND lvl2.ParentGroupID=lvl1.GroupID 
     FOR XML PATH('productGroup2'),TYPE 
     ) 
FROM #tmpFullResult AS lvl1 
WHERE lvl1.ParentGroupID IS NULL 
FOR XML PATH('productgroup1'),ROOT('root') 
GO 
DROP TABLE #tmpFullResult; 
DROP TABLE #GroupProductRelations 
DROP TABLE #Groups 
DROP TABLE #GroupRelations 
DROP TABLE #Languages 
DROP TABLE #Products 

Das Ergebnis

<root> 
    <productgroup1> 
    <groupName>AAA</groupName> 
    <productGroup2> 
     <groupName>BBB</groupName> 
     <productGroup3> 
     <groupName>CCC</groupName> 
     <products> 
      <product> 
      <itemName>ABC</itemName> 
      <itemNumber>100101</itemNumber> 
      <itemPrice>159.6100</itemPrice> 
      <ExtraProductgroup> 
       <extraProductGroupName>GGG</extraProductGroupName> 
       <itemName>FRE</itemName> 
       <itemNumber>100105</itemNumber> 
       <itemPrice>159.6100</itemPrice> 
      </ExtraProductgroup> 
      </product> 
      <product> 
      <itemName>BCD</itemName> 
      <itemNumber>100102</itemNumber> 
      <itemPrice>159.6100</itemPrice> 
      <ExtraProductgroup> 
       <extraProductGroupName>GGG</extraProductGroupName> 
       <itemName>FRE</itemName> 
       <itemNumber>100105</itemNumber> 
       <itemPrice>159.6100</itemPrice> 
      </ExtraProductgroup> 
      </product> 
     </products> 
     </productGroup3> 
    </productGroup2> 
    </productgroup1> 
</root> 
+0

@AntonTredder Nun, manchmal müssen wir die Dinge nehmen, wie sie sind ... Was ich im Moment nicht verstehe: Ist diese Frage gelöst (gegebene Daten => erwartete Ausgabe) oder nicht? Wenn nicht: Warum nicht? – Shnugo

+0

@AntonTredder fügen Sie bitte einige Zeilen zu Ihren Beispieldaten in Ihrer Frage hinzu, um das zu reflektieren (benutzen Sie die redigierenwahl) und fiddle sie in Ihre erwartete Ausgabe auch verstehe nicht wirklich, was du willst/brauchst ... – Shnugo

+0

@AntonTredder, Du hast gerade genau die gleiche Frage gestellt, das ist eine gute Entscheidung, denn sie zieht viel mehr Anziehungskraft auf diese komplexe Frage ein Rollback zu deinen letzten Änderungen hier und schließe diese Frage.Wie ich so investiert habe mir zeit und tatsächlich die gestellte frage mit den angegebenen daten gelöst würde ich dich bitten, mich abzustimmen und (zusatzaktion) ankreuzen die akzeptanzprüfung, um diese frage zu schließen. Ich melde mich bei deiner neuen Frage (morgen) und helfe dir dort - wenn ich kann ... Thx – Shnugo

Verwandte Themen