Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да премахна излишното пространство от имена във вложена заявка, когато използвам FOR XML PATH

След часове на отчаяние и стотици опити и грешки стигнах до решението по-долу.

Имах същия проблем, когато исках само един xmlns атрибут, в корена възелсамо . Но също така имах много трудна заявка с много подзаявки и FOR XML EXPLICIT методът сам по себе си беше твърде тромав. Така че да, исках удобството на FOR XML PATH в подзаявките и също така да задам моите собствени xmlns .

Любезно взех назаем кода от 8kb's отговор, защото беше толкова хубаво. Промених го малко за по-добро разбиране. Ето кода:

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

Резултат:

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

Ако сте избрали @xml сам, ще видите, че съдържа основен възел dummyTag . Не се нуждаем от него, затова го премахваме с помощта на директива xmltext в FOR XML EXPLICIT заявка:

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

Въпреки че обяснението в MSDN звучи по-сложно, но на практика то казва на анализатора да избере съдържанието на XML коренен възел.

Не съм сигурен колко бърза е заявката, но в момента си почивам и пия скоч като джентълмен, докато мирно гледам кода...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. sql server 2008 management studio не проверява синтаксиса на моята заявка

  2. запитване на двоична колона, като се използва като в sql сървър

  3. Как да използвате FILEPROPERTY() в SQL Server

  4. SqlCommand.ExecuteScalar Отказ

  5. Ограничете редовете, върнати в заявка на SQL Server, като използвате клаузата TOP