sql >> Database teknologi >  >> RDS >> Sqlserver

Hvordan fjerner jeg redundant navneområde i indlejret forespørgsel, når jeg bruger FOR XML PATH

Efter timers desperation og hundredvis af forsøg og fejl har jeg fundet nedenstående løsning.

Jeg havde det samme problem, da jeg ville have bare én xmlns attribut, på roden kun node . Men jeg havde også en meget vanskelig forespørgsel med masser af underforespørgsler og FOR XML EXPLICIT metoden alene var bare for besværlig. Så ja, jeg ønskede bekvemmeligheden ved FOR XML PATH i underforespørgslerne og også for at indstille mine egne xmlns .

Jeg lånte venligst koden til 8kb'er svar, fordi det var så hyggeligt. Jeg tilpassede det lidt for bedre forståelse. Her er koden:

DECLARE @Order TABLE (OrderID INT, OrderDate DATETIME)    
DECLARE @OrderDetail TABLE (OrderID INT, ItemID VARCHAR(1), Name VARCHAR(50), Qty INT)    
INSERT @Order VALUES (1, '2010-01-01'), (2, '2010-01-02')    
INSERT @OrderDetail VALUES (1, 'A', 'Drink',  5),
                           (1, 'B', 'Cup',    2),
                           (2, 'A', 'Drink',  2),
                           (2, 'C', 'Straw',  1),
                           (2, 'D', 'Napkin', 1)

-- Your ordinary FOR XML PATH query
DECLARE @xml XML = (SELECT OrderID AS "@OrderID",
                        (SELECT ItemID AS "@ItemID", 
                                Name AS "data()" 
                         FROM @OrderDetail 
                         WHERE OrderID = o.OrderID 
                         FOR XML PATH ('Item'), TYPE)
                    FROM @Order o 
                    FOR XML PATH ('Order'), ROOT('dummyTag'), TYPE)

-- Magic happens here!       
SELECT 1 AS Tag
      ,NULL AS Parent
      ,@xml AS [xml!1!!xmltext]
      ,'http://test.com/order' AS [xml!1!xmlns]
FOR XML EXPLICIT

Resultat:

<xml xmlns="http://test.com/order">
  <Order OrderID="1">
    <Item ItemID="A">Drink</Item>
    <Item ItemID="B">Cup</Item>
  </Order>
  <Order OrderID="2">
    <Item ItemID="A">Drink</Item>
    <Item ItemID="C">Straw</Item>
    <Item ItemID="D">Napkin</Item>
  </Order>
</xml>

Hvis du valgte @xml alene, ville du se, at den indeholder rodnode dummyTag . Vi har ikke brug for det, så vi fjerner det ved at bruge direktivet xmltext i FOR XML EXPLICIT forespørgsel:

,@xml AS [xml!1!!xmltext]

Selvom forklaringen i MSDN lyder mere sofistikeret, men praktisk talt fortæller den parseren at vælge indholdet af XML rodknude.

Ikke sikker på, hvor hurtig forespørgslen er, men i øjeblikket slapper jeg af og drikker skotsk som en herre, mens jeg fredeligt kigger på koden...



  1. Grails-transaktionssætSavePoint-metoden på mysql forårsager undtagelse

  2. Undslippe søgeordslignende kolonnenavne i Postgres

  3. Er der nogen grund til ikke at bruge lagrede procedurer for hver forespørgsel?

  4. GroupingError:ERROR:kolonnen skal vises i GROUP BY-sætningen eller bruges i en aggregeret funktion