Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Làm cách nào để loại bỏ không gian tên thừa trong truy vấn lồng nhau khi sử dụng FOR XML PATH

Sau hàng giờ tuyệt vọng và hàng trăm lần thử và sai, tôi đã đưa ra giải pháp bên dưới.

Tôi đã gặp vấn đề tương tự, khi tôi muốn chỉ một xmlns thuộc tính trên root nút chỉ . Nhưng tôi cũng gặp phải một truy vấn rất khó với rất nhiều truy vấn con và FOR XML EXPLICIT một mình phương pháp đã quá cồng kềnh. Vì vậy, có, tôi muốn sự tiện lợi của FOR XML PATH trong các truy vấn con và cũng để đặt xmlns của riêng tôi .

Tôi vui lòng mượn mã của 8kb's câu trả lời, bởi vì nó rất hay. Tôi đã chỉnh sửa nó một chút để hiểu rõ hơn. Đây là mã:

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

Kết quả:

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

Nếu bạn đã chọn @xml một mình, bạn sẽ thấy rằng nó chứa nút gốc dummyTag . Chúng tôi không cần nó, vì vậy chúng tôi xóa nó bằng cách sử dụng chỉ thị xmltext trong FOR XML EXPLICIT truy vấn:

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

Mặc dù lời giải thích trong MSDN nghe có vẻ phức tạp hơn, nhưng trên thực tế, nó yêu cầu trình phân tích cú pháp chọn nội dung của XML nút gốc.

Không chắc truy vấn nhanh đến mức nào, nhưng hiện tại tôi đang thư giãn và uống Scotch như một người bạn trong khi yên tâm xem mã ...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Đối số tùy chọn trong mệnh đề WHERE

  2. Các phương pháp hay nhất để sử dụng GUID làm khóa chính, cụ thể là về hiệu suất là gì?

  3. Tạo một bảng tạm thời dựa trên một bảng khác trong SQL Server

  4. Khôi phục cơ sở dữ liệu SQL Server Master

  5. Trả lại ID trên INSERT?