sql >> データベース >  >> RDS >> Sqlserver

FOR XML PATHを使用するときに、ネストされたクエリで冗長な名前空間を削除するにはどうすればよいですか?

    何時間もの絶望と何百もの試行錯誤の末、私は以下の解決策を思いつきました。

    1つだけが必要だったときに同じ問題が発生しました xmlns ルートの属性 ノードのみ 。しかし、多くのサブクエリとFOR XML EXPLICITを使用した非常に難しいクエリもありました。 方法だけでは面倒でした。そうです、FOR XML PATHの便利さが欲しかったのです。 サブクエリで、また独自のxmlnsを設定します 。

    8kbののコードを親切に借りました それはとても素晴らしかったので、答えます。理解を深めるために少し調整しました。コードは次のとおりです:

    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が含まれていることがわかります。 。不要なので、ディレクティブ<を使用して削除します。 / a> xmltext FOR XML EXPLICIT クエリ:

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

    MSDNの説明はより洗練されているように聞こえますが、実際には、パーサーにコンテンツを選択するように指示しています。 XMLの ルートノード。

    クエリの速度はわかりませんが、現在、コードを静かに見ながら、リラックスしてスコッチを紳士のように飲んでいます...



    1. EntityFrameworkおよびMySQLとの楽観的同時実行性

    2. バックエンドデータベースが新しい場所に移動した後、Access2016でリンクされたテーブルを更新する方法

    3. PostgreSQLスキーマ/Djangoを使用した名前空間

    4. Oracleで日時値から秒数を返す方法