Aracılığıyla paylaş


XML Sorgusunda İç İçe FOR XML Sorgusu ile Karşılaştırma

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen ÖrneğiMicrosoft Fabric'te SQL veritabanı

Bu makalede, tek düzeyli FOR XML sorgu ile iç içe FOR XML sorgu karşılaştırılmaktadır. İç içe FOR XML sorguları kullanmanın avantajlarından biri, sorgu sonuçları için öznitelik merkezli ve öğe merkezli XML birleşimini belirtebilmenizdir. Örnekte bu avantaj gösterilmektedir.

Bu makaledeki kod örnekleri, AdventureWorks2025 giriş sayfasından indirebileceğiniz AdventureWorksDW2025 veya örnek veritabanını kullanır.

Örnekler

Aşağıdaki SELECT sorgu, veritabanındaki ürün kategorisi ve alt kategori bilgilerini AdventureWorks2025 alır. Sorguda iç içe FOR XML yok.

USE AdventureWorks2022;
GO

SELECT ProductCategory.ProductCategoryID,
    ProductCategory.Name AS CategoryName,
    ProductSubCategory.ProductSubCategoryID,
    ProductSubCategory.Name
FROM Production.ProductCategory,
    Production.ProductSubCategory
WHERE ProductCategory.ProductCategoryID = ProductSubCategory.ProductCategoryID
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE;
GO

Kısmi sonuç aşağıdadır:

<ProductCategory ProductCategoryID="1" CategoryName="Bike">
  <ProductSubCategory ProductSubCategoryID="1" Name="Mountain Bike"/>
  <ProductSubCategory ProductSubCategoryID="2" Name="Road Bike"/>
  <ProductSubCategory ProductSubCategoryID="3" Name="Touring Bike"/>
</ProductCategory>
...

Sorguda yönergesini ELEMENTS belirtirseniz, aşağıdaki sonuç parçasında gösterildiği gibi öğe merkezli bir sonuç alırsınız:

<ProductCategory>
  <ProductCategoryID>1</ProductCategoryID>
  <CategoryName>Bike</CategoryName>
  <ProductSubCategory>
    <ProductSubCategoryID>1</ProductSubCategoryID>
    <Name>Mountain Bike</Name>
  </ProductSubCategory>
  <ProductSubCategory>
     ...
  </ProductSubCategory>
</ProductCategory>

Ardından, aşağıdaki parçada gösterildiği gibi öznitelik merkezli ve öğe merkezli XML'nin birleşimi olan bir XML hiyerarşisi oluşturmak istediğinizi varsayalım:

<ProductCategory ProductCategoryID="1" CategoryName="Bike">
  <ProductSubCategory>
    <ProductSubCategoryID>1</ProductSubCategoryID>
    <SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>
  <ProductSubCategory>
     ...
  <ProductSubCategory>
     ...
</ProductCategory>

Önceki parçada, kategori kimliği ve kategori adı gibi ürün kategorisi bilgileri özniteliklerdir. Ancak, alt kategori bilgileri öğe odaklıdır. <ProductCategory> öğesini oluşturmak için, aşağıdaki gibi bir FOR XML sorgusu yazabilirsiniz.

SELECT ProductCategoryID,
    Name AS CategoryName
FROM Production.ProductCategory ProdCat
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE;

Sonuç şu şekildedir:

< ProdCat ProductCategoryID="1" CategoryName="Bikes" />
< ProdCat ProductCategoryID="2" CategoryName="Components" />
< ProdCat ProductCategoryID="3" CategoryName="Clothing" />
< ProdCat ProductCategoryID="4" CategoryName="Accessories" />

İstediğiniz XML'de iç içe <ProductSubCategory> öğeleri oluşturmak için, aşağıdaki kod örneğinde gösterildiği gibi iç içe FOR XML bir sorgu eklersiniz:

SELECT ProductCategoryID,
    Name AS CategoryName,
    (
        SELECT ProductSubCategoryID, Name AS SubCategoryName
        FROM Production.ProductSubCategory
        WHERE ProductSubCategory.ProductCategoryID = ProductCategory.ProductCategoryID
        FOR XML AUTO, TYPE, ELEMENTS
    )
FROM Production.ProductCategory
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE;

Önceki sorguda aşağıdakilere dikkat edin:

  • İç FOR XML sorgu, ürün alt kategorisi bilgilerini alır. İç ELEMENTS içine FOR XML yönergesi eklenir, böylece dış sorgu tarafından oluşturulan XML'ye eklenen öğe odaklı XML oluşturulur. Varsayılan olarak, dış sorgu öznitelik merkezli XML oluşturur.

  • İç sorguda yönergesi TYPE belirtilir, dolayısıyla sonuç xml türünde olur. Belirtilmezse TYPE , sonuç nvarchar(max) türü olarak döndürülür ve XML verileri varlık olarak döndürülür.

  • Ayrıca dış sorgu TYPE yönergesini belirtir. Bu nedenle, bu sorgunun sonucu istemciye xml türü olarak döndürülür.

Kısmi sonuç aşağıdadır:

<ProductCategory ProductCategoryID="1" CategoryName="Bike">
  <ProductSubCategory>
    <ProductSubCategoryID>1</ProductSubCategoryID>
    <SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>
  <ProductSubCategory>
     ...
  <ProductSubCategory>
     ...
</ProductCategory>

Aşağıdaki sorgu yalnızca önceki sorgunun bir uzantısıdır. AdventureWorks2025 veritabanında ürünlerin tam hiyerarşisini gösterir. Buna aşağıdakiler dahildir:

  • Ürün kategorileri
  • Her kategorideki ürün alt kategorileri
  • Her alt kategorideki ürün modelleri
  • Her modeldeki ürünler

Veritabanını anlamak için aşağıdaki sorguyu AdventureWorks2025 yararlı bulabilirsiniz:

SELECT ProductCategoryID,
    Name AS CategoryName,
    (
        SELECT ProductSubCategoryID,
            Name AS SubCategoryName,
            (
                SELECT ProductModel.ProductModelID,
                    ProductModel.Name AS ModelName,
                    (
                        SELECT ProductID, Name AS ProductName, Color
                        FROM Production.Product
                        WHERE Product.ProductModelID = ProductModel.ProductModelID
                        FOR XML AUTO, TYPE
                    )
                FROM (
                    SELECT DISTINCT ProductModel.ProductModelID, ProductModel.Name
                    FROM Production.ProductModel, Production.Product
                    WHERE ProductModel.ProductModelID = Product.ProductModelID
                        AND Product.ProductSubCategoryID = ProductSubCategory.ProductSubCategoryID
                    ) ProductModel
                FOR XML AUTO, TYPE
                )
        FROM Production.ProductSubCategory
        WHERE ProductSubCategory.ProductCategoryID = ProductCategory.ProductCategoryID
        FOR XML AUTO, TYPE, ELEMENTS
    )
FROM Production.ProductCategory
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE;

Kısmi sonuç aşağıdadır:

<Production.ProductCategory ProductCategoryID="1" CategoryName="Bikes">
  <Production.ProductSubCategory>
    <ProductSubCategoryID>1</ProductSubCategoryID>
    <SubCategoryName>Mountain Bikes</SubCategoryName>
    <ProductModel ProductModelID="19" ModelName="Mountain-100">
      <Production.Product ProductID="771"
                ProductName="Mountain-100 Silver, 38" Color="Silver" />
      <Production.Product ProductID="772"
                ProductName="Mountain-100 Silver, 42" Color="Silver" />
      <Production.Product ProductID="773"
                ProductName="Mountain-100 Silver, 44" Color="Silver" />
        ...
    </ProductModel>
     ...

Ürün alt kategorileri oluşturan iç içe ELEMENTS sorgudaki FOR XML yönergesini kaldırırsanız, sonucun tamamı öznitelik merkezli olur. Daha sonra bu sorguyu iç içe yerleştirmeden yazabilirsiniz. ELEMENTS eklenmesi, kısmen öznitelik merkezli ve kısmen öğe merkezli bir XML ortaya çıkarır. Bu sonuç tek FOR XML düzeyli bir sorgu tarafından oluşturulamaz.