sql >> Databasteknik >  >> RDS >> Sqlserver

Hur tar jag bort redundant namnutrymme i kapslad fråga när jag använder FOR XML PATH

Efter timmar av desperation och hundratals försök och misstag har jag kommit fram till lösningen nedan.

Jag hade samma problem när jag ville ha bara en xmlns attribut, på roten endast nod . Men jag hade också en mycket svår fråga med många underfrågor och FOR XML EXPLICIT Bara metoden var alldeles för besvärlig. Så ja, jag ville ha bekvämligheten med FOR XML PATH i underfrågorna och även för att ställa in mina egna xmlns .

Jag lånade koden för 8kb's svar, för det var så fint. Jag justerade det lite för bättre förståelse. Här är 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>

Om du valde @xml ensam skulle du se att den innehåller rotnoden dummyTag . Vi behöver det inte, så vi tar bort det genom att använda direktivet xmltext i FOR XML EXPLICIT fråga:

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

Även om förklaringen i MSDN låter mer sofistikerad, men praktiskt taget säger den till parsern att välja innehållet av XML rotnod.

Jag är inte säker på hur snabb frågan är, men för närvarande slappar jag av och dricker Scotch som en herre medan jag lugnt tittar på koden...



  1. Guide till att använda Sphinx med PHP och MySQL

  2. Hur får man medelvärdet av de "mitten" värdena i en grupp?

  3. Hur man beräknar löpande summa för varje grupp i MySQL

  4. Närmaste match, del 1