FOR XML 쿼리 및 중첩 FOR XML 쿼리 비교
적용 대상: SQL Server Azure SQL 데이터베이스 Azure SQL Managed Instance
이 문서에서는 단일 수준 FOR XML
쿼리를 중첩FOR XML
쿼리와 비교합니다. 중첩된 FOR XML
쿼리를 사용할 경우의 이점 중 하나는 쿼리 결과에 특성 중심 및 요소 중심 XML의 조합을 지정할 수 있다는 것입니다. 이 예제에서는 이러한 이점을 보여 줍니다.
이 문서의 Transact-SQL 코드 샘플은 AdventureWorks2022
또는 AdventureWorksDW2022
샘플 데이터베이스를 사용하며, 이는 Microsoft SQL Server 예시 및 커뮤니티 프로젝트(Microsoft SQL Server Samples and Community Projects) 홈 페이지에서 다운로드할 수 있습니다.
예제
다음 SELECT
쿼리는 AdventureWorks2022
데이터베이스에서 제품 범주와 하위 범주 정보를 검색합니다. 쿼리에 중첩 FOR XML
이 없습니다.
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
다음은 결과의 일부입니다.
<ProductCategory ProductCategoryID="1" CategoryName="Bike">
<ProductSubCategory ProductSubCategoryID="1" Name="Mountain Bike"/>
<ProductSubCategory ProductSubCategoryID="2" Name="Road Bike"/>
<ProductSubCategory ProductSubCategoryID="3" Name="Touring Bike"/>
</ProductCategory>
...
쿼리에서 ELEMENTS
지시문을 지정하면 다음 결과 조각과 같이 요소 중심 결과가 수신됩니다.
<ProductCategory>
<ProductCategoryID>1</ProductCategoryID>
<CategoryName>Bike</CategoryName>
<ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<Name>Mountain Bike</Name>
</ProductSubCategory>
<ProductSubCategory>
...
</ProductSubCategory>
</ProductCategory>
다음으로, 다음 조각과 같이 특성 중심 XML과 요소 중심 XML의 조합인 XML 계층을 생성한다고 가정합니다.
<ProductCategory ProductCategoryID="1" CategoryName="Bike">
<ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>
<ProductSubCategory>
...
<ProductSubCategory>
...
</ProductCategory>
이전 조각에서 범주 ID 및 범주 이름과 같은 제품 범주 정보는 특성입니다. 그러나 하위 범주 정보는 요소 중심입니다. <ProductCategory>
요소를 생성하기 위해 다음과 같이 FOR XML
쿼리를 작성할 수 있습니다.
SELECT ProductCategoryID,
Name AS CategoryName
FROM Production.ProductCategory ProdCat
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE;
결과:
< ProdCat ProductCategoryID="1" CategoryName="Bikes" />
< ProdCat ProductCategoryID="2" CategoryName="Components" />
< ProdCat ProductCategoryID="3" CategoryName="Clothing" />
< ProdCat ProductCategoryID="4" CategoryName="Accessories" />
원하는 XML에서 중첩 <ProductSubCategory>
요소를 생성하려면 다음 코드 샘플과 같이 중첩 FOR XML
쿼리를 추가합니다.
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;
이전 쿼리의 다음 사항에 유의하세요.
내부
FOR XML
쿼리는 제품 하위 범주 정보를 검색합니다. 외부 쿼리에서 생성된 XML에 추가되는 요소 중심 XML을 생성하기 위해 내부FOR XML
에ELEMENTS
지시문이 추가됩니다. 기본적으로 외부 쿼리는 특성 중심 XML을 생성합니다.내부 쿼리에서 결과가 xml 형식이 되도록
TYPE
지시문이 지정됩니다.TYPE
을 지정하지 않으면 결과가 nvarchar(max) 형식으로 반환되고 XML 데이터가 엔터티로 반환됩니다.다음 쿼리는
TYPE
지시문도 지정합니다. 따라서 이 쿼리의 결과는 xml 형식으로 클라이언트에 반환됩니다.
다음은 결과의 일부입니다.
<ProductCategory ProductCategoryID="1" CategoryName="Bike">
<ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>
<ProductSubCategory>
...
<ProductSubCategory>
...
</ProductCategory>
다음 쿼리는 이전 쿼리의 확장에 불과합니다. AdventureWorks2022
데이터베이스의 전체 제품 계층 구조가 표시됩니다. 다음 내용이 포함됩니다.
- 제품 범주
- 각 범주의 제품 하위 범주
- 각 하위 범주의 제품 모델
- 각 모델의 제품
다음 쿼리는 AdventureWorks2022
데이터베이스를 이해하는 데 도움이 됩니다.
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;
다음은 결과의 일부입니다.
<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>
...
제품 하위 범주를 생성하는 중첩된 ELEMENTS
쿼리에서 FOR XML
지시어를 제거하면 전체 결과가 특성 중심이 됩니다. 그런 다음 중첩하지 않고 이 쿼리를 작성할 수 있습니다. 부분적으로 특성 중심이고 부분적으로 요소 중심인 XML에 ELEMENTS
결과를 추가합니다. 이 결과는 단일 수준 FOR XML
쿼리로 생성할 수 없습니다.