PATH 모드 사용

FOR XML을 사용하는 XML 생성 항목에 설명된 대로 PATH 모드를 사용하면 요소와 특성을 간단하게 혼합할 수 있고 추가 중첩을 간단하게 도입하여 복잡한 속성을 표시할 수 있습니다. FOR XML EXPLICIT 모드 쿼리를 사용하여 행 집합에서 해당 XML을 생성할 수 있지만 PATH 모드를 사용할 경우 복잡해지기 쉬운 EXPLICIT 모드 쿼리의 대안을 찾을 수 있습니다. XML 유형 인스턴스를 반환하는 중첩 FOR XML 쿼리 및 TYPE 지시어 작성 기능과 함께 PATH 모드를 사용하면 보다 간편하게 쿼리를 작성할 수 있습니다.

PATH 모드에서는 열 이름이나 열 별칭이 XPath 식으로 처리됩니다. 이러한 식은 값이 XML에 매핑되는 방법을 나타냅니다. 각 XPath 식은 특성, 요소와 스칼라 값 및 행 요소에 대해 생성되는 노드의 이름과 계층 등의 항목 유형을 제공하는 상대 XPath입니다.

이 항목에서는 행 집합의 열을 매핑하는 다음 조건에 대해 설명합니다.

  • 이름이 없는 열
  • 이름이 있는 열
  • 이름이 와일드카드 문자(*)로 지정된 열
  • 이름이 XPath 노드 테스트인 열
  • 경로가 **data()**로 지정된 열 이름
  • 기본적으로 NULL 값을 포함하는 열

이름이 없는 열

이름이 없는 열은 인라인됩니다. 예를 들어 계산 열이나 열 별칭을 지정하지 않는 중첩된 스칼라 쿼리는 이름이 없는 열을 생성합니다. xml 유형의 열일 경우 해당 데이터 유형 인스턴스의 내용이 삽입됩니다. 그렇지 않을 경우에는 열 내용이 텍스트 노드로 삽입됩니다.

SELECT 2+2
FOR XML PATH

이 XML을 생성합니다. 기본적으로 행 집합의 각 행에 대해 결과 XML에 <row> 요소가 생성됩니다. 이 동작은 RAW 모드와 동일합니다.

<row>4</row>

다음 쿼리는 3개의 열로 구성된 행 집합을 반환합니다. 이름이 없는 세 번째 열에는 XML 데이터가 포함됩니다. PATH 모드는 xml 유형의 인스턴스를 삽입합니다.

SELECT ProductModelID,
       Name,
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
                /MI:root/MI:Location 
              ') 
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH 
go

다음은 결과의 일부입니다.

<row>
  <ProductModelID>7</ProductModelID>
  <Name>HL Touring Frame</Name>
  <MI:Location ...LocationID="10" ...></MI:Location>
  <MI:Location ...LocationID="20" ...></MI:Location>
   ...
</row>

이름이 있는 열

다음은 이름이 있는 행 집합 열이 대/소문자를 구분하여 결과 XML에 매핑되는 특정 조건입니다.

  • 열 이름이 @ 기호로 시작하는 경우
  • 열 이름이 @ 기호로 시작하지 않는 경우
  • 열 이름이 @ 기호로 시작하지 않고 슬래시 기호(/)를 포함하는 경우
  • 여러 열이 같은 접두사를 공유하는 경우
  • 하나의 열에 다른 이름이 있는 경우

열 이름이 @ 기호로 시작하는 경우

열 이름이 @ 기호로 시작하고 슬래시 기호(/)를 포함하지 않는 경우 해당 열 값을 갖는 <row> 요소의 특성이 생성됩니다. 예를 들어 다음 쿼리는 2개의 열(@PmId, Name)로 구성된 행 집합을 반환합니다. 결과 XML에서 PmId 특성이 해당 <row> 요소에 추가되고 ProductModelID의 값이 여기에 할당됩니다.

SELECT ProductModelID as "@PmId",
       Name
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH 
go

다음은 결과입니다.

<row PmId="7">
  <Name>HL Touring Frame</Name>
</row>

특성은 같은 수준에서 요소 노드, 텍스트 노드 등 다른 노드 유형 앞에 와야 합니다. 다음 쿼리는 오류를 반환합니다.

SELECT Name,
       ProductModelID as "@PmId"
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH 
go

열 이름이 @ 기호로 시작하지 않는 경우

열 이름이 @ 기호로 시작하지 않고 XPath 노드 테스트 중 하나가 아니며 슬래시 기호(/)를 포함하지 않는 경우 기본적으로 <row> 행 요소의 하위 요소인 XML 요소가 생성됩니다.

다음 쿼리는 결과인 열 이름을 지정합니다. 따라서 <result> 요소 자식이 <row> 요소에 추가됩니다.

SELECT 2+2 as result
for xml PATH

다음은 결과입니다.

<row>
  <result>4</result>
</row>

다음 쿼리는 xml 유형의 Instructions 열에 대해 지정된 XQuery에서 반환하는 XML에 대해 열 이름 ManuWorkCenterInformation을 지정합니다. 따라서 <ManuWorkCenterInformation> 요소가 <row> 요소의 자식으로 추가됩니다.

SELECT 
       ProductModelID,
       Name,
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
                /MI:root/MI:Location 
              ') as ManuWorkCenterInformation
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH 
go

다음은 결과입니다.

<row>
  <ProductModelID>7</ProductModelID>
  <Name>HL Touring Frame</Name>
  <ManuWorkCenterInformation>
    <MI:Location ...LocationID="10" ...></MI:Location>
    <MI:Location ...LocationID="20" ...></MI:Location>
     ...
  </ManuWorkCenterInformation>
</row>

열 이름이 @ 기호로 시작하지 않고 슬래시 기호(/)를 포함하는 경우

열 이름이 @ 기호로 시작하지 않지만 슬래시 기호(/)를 포함할 경우 열 이름은 XML 계층을 나타냅니다. 예를 들어 열 이름이 "Name1/Name2/Name3.../Namen "이면 각 Namei는 현재 행 요소(i=1인 경우)에 중첩된 요소 이름을 나타내거나 이름이 Namei-1인 요소 아래의 요소 이름을 나타냅니다. Namen이 '@'으로 시작하는 경우 Namen-1 요소의 특성에 매핑됩니다.

예를 들어 다음 쿼리는 이름, 중간 이름 및 성을 포함하는 복잡한 요소 EmpName으로 표현되는 직원 ID와 이름을 반환합니다.

SELECT EmployeeID "@EmpID", 
       FirstName  "EmpName/First", 
       MiddleName "EmpName/Middle", 
       LastName   "EmpName/Last"
FROM   HumanResources.Employee E, Person.Contact C
WHERE  E.EmployeeID = C.ContactID
AND    E.EmployeeID=1
FOR XML PATH

PATH 모드에서 XML을 생성할 때 열 이름이 경로로 사용됩니다. 직원 ID 값을 포함하는 열 이름이 '@'으로 시작하므로 EmpID 특성이 <row> 요소에 추가됩니다. 다른 모든 열에는 계층을 나타내는 열 이름에 슬래시 기호('/')가 있습니다. 결과 XML은 <row> 요소 아래에 <EmpName> 자식을 포함하고 <EmpName> 자식은 <First>, <Middle> 및 <Last> 요소 자식을 갖습니다.

<row EmpID="1">
  <EmpName>
    <First>Gustavo</First>
    <Last>Achong</Last>
  </EmpName>
</row>

직원 중간 이름은 Null이며 기본적으로 Null 값이 매핑할 요소나 특성이 없습니다. NULL 값에 대해 요소를 생성하려는 경우 이 쿼리에서와 같이 ELEMENTS 지시어와 XSINIL을 함께 지정할 수 있습니다.

SELECT EmployeeID "@EmpID", 
       FirstName  "EmpName/First", 
       MiddleName "EmpName/Middle", 
       LastName   "EmpName/Last"
FROM   HumanResources.Employee E, Person.Contact C
WHERE  E.EmployeeID = C.ContactID
AND    E.EmployeeID=1
FOR XML PATH, ELEMENTS XSINIL

다음은 결과입니다.

<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      EmpID="1">
  <EmpName>
    <First>Gustavo</First>
    <Middle xsi:nil="true" />
    <Last>Achong</Last>
  </EmpName>
</row>

기본적으로 PATH 모드는 요소 중심의 XML을 생성하므로 PATH 모드 쿼리에 ELEMENTS 지시어를 지정하면 아무 영향도 미치지 않습니다. 그러나 이전 예에서와 같이 ELEMENTS 지시어를 XSINIL과 함께 사용하면 Null 값에 대한 요소를 생성하는 데 유용합니다.

다음 쿼리에서는 ID와 이름 외에 직원 주소를 검색합니다. 주소 열에 대한 열 이름에 있는 각 경로대로 <Address> 요소 자식이 <row> 요소에 추가되고 주소 정보가 <Address> 요소의 요소 자식으로 추가됩니다.

SELECT EmployeeID   "@EmpID", 
       FirstName    "EmpName/First", 
       MiddleName   "EmpName/Middle", 
       LastName     "EmpName/Last",
       AddressLine1 "Address/AddrLine1",
       AddressLine2 "Address/AddrLIne2",
       City         "Address/City"
FROM   HumanResources.Employee E, Person.Contact C, Person.Address A
WHERE  E.EmployeeID = C.ContactID
AND    E.AddressID = A.AddressID
AND    E.EmployeeID=1
FOR XML PATH

다음은 결과입니다.

<row EmpID="1">
  <EmpName>
    <First>Gustavo</First>
    <Last>Achong</Last>
  </EmpName>
  <Address>
    <AddrLine1>7726 Driftwood Drive</AddrLine1>
    <City>Monroe</City>
  </Address>
</row>

여러 열이 같은 경로 접두사를 공유하는 경우

이어지는 여러 열이 같은 경로 접두사를 공유할 경우 같은 이름으로 함께 그룹화됩니다. 다른 네임스페이스 접두사가 사용되면 같은 네임스페이스로 바인딩되더라도 경로가 다르다고 간주됩니다. 이전 쿼리에서 FirstName, MiddleName 및 LastName 열은 동일한 EmpName 접두사를 공유하므로 <EmpName> 요소의 자식으로 추가됩니다. 이전 예제에서 <Address> 요소를 만들던 것도 이와 같은 경우입니다.

하나의 열에 다른 이름이 있는 경우

이름이 다른 열이 중간에 나타나면 다음의 수정된 쿼리에서와 같이 그룹화가 해제됩니다. 쿼리는 FirstName 열과 MiddleName 열 사이에 주소 열을 추가하여 이전 쿼리에 지정된 대로 FirstName, MiddleName 및 LastName의 그룹화를 해제합니다.

SELECT EmployeeID "@EmpID", 
       FirstName "EmpName/First", 
       AddressLine1 "Address/AddrLine1",
       AddressLine2 "Address/AddrLIne2",
       City "Address/City",
       MiddleName "EmpName/Middle", 
       LastName "EmpName/Last"
FROM   HumanResources.EmployeeAddress E, Person.Contact C, Person.Address A
WHERE  E.EmployeeID = C.ContactID
AND    E.AddressID = A.AddressID
AND    E.EmployeeID=1
FOR XML PATH

그 결과 두 개의 <EmpName> 요소가 생성됩니다. 첫 번째 <EmpName> 요소는 <FirstName> 요소 자식을 포함하고 두 번째 <EmpName> 요소는 <MiddleName> 및 <LastName> 요소 자식을 포함합니다.

다음은 결과입니다.

<row EmpID="1">
  <EmpName>
    <First>Gustavo</First>
  </EmpName>
  <Address>
    <AddrLine1>7726 Driftwood Drive</AddrLine1>
    <City>Monroe</City>
  </Address>
  <EmpName>
    <Last>Achong</Last>
  </EmpName>
</row>

이름이 와일드카드 문자(*)로 지정된 열

지정된 열 이름이 와일드카드 문자(*)이면 열 이름이 지정되지 않은 경우처럼 열 내용이 삽입됩니다. 이 열이 비-xml 유형 열이면 다음 예에서와 같이 열 내용이 텍스트 노드로 삽입됩니다.

SELECT EmployeeID "@EmpID", 
       FirstName "*", 
       MiddleName "*", 
       LastName "*"
FROM   HumanResources.Employee E, Person.Contact C
WHERE  E.EmployeeID = C.ContactID
AND    E.EmployeeID=1
FOR XML PATH

다음은 결과입니다.

<row EmpID="1">GustavoAchong</row>

열이 xml 유형일 경우 해당 XML 트리가 삽입됩니다. 예를 들어 다음 쿼리는 Instructions 열에 대해 XQuery에서 반환한 XML이 포함된 열 이름에 "*"를 지정합니다.

SELECT 
       ProductModelID,
       Name,
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"
                /MI:root/MI:Location 
              ') as "*"
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH 
go

다음은 결과입니다. XQuery에서 반환한 XML이 래핑 요소 없이 삽입됩니다.

<row>
  <ProductModelID>7</ProductModelID>
  <Name>HL Touring Frame</Name>
  <MI:Location LocationID="10">...</MI:Location>
  <MI:Location LocationID="20">...</MI:Location>
...
</row>

이름이 XPath 노드 테스트인 열

열 이름이 XPath 노드 테스트 중 하나일 경우 다음 표에서와 같이 내용이 매핑됩니다.

열 이름이 XPath 노드 테스트이면 내용이 해당 노드로 매핑됩니다. 열의 SQL 유형이 xml이면 오류가 반환됩니다.

열 이름 동작

text()

이름이 text()인 열의 경우 열의 문자열 값이 텍스트 노드로 추가됩니다.

comment()

이름이 comment()인 열의 경우 열의 문자열 값이 XML 주석으로 추가됩니다.

node()

이름이 node()인 열의 경우 열 이름이 와일드카드 문자(*)일 때와 결과가 같습니다.

processing-instruction(name)

이름이 처리 명령인 열의 경우 열의 문자열 값이 처리 명령 대상 이름의 PI 값으로 추가됩니다.

경로가 data()로 지정된 열 이름

열 이름으로 지정된 경로가 "data()"일 경우 생성된 XML에서 해당 값이 원자성 값으로 처리됩니다. 직렬화의 다음 항목도 원자성 값이면 공백 문자가 XML에 추가됩니다. 이 특징은 목록 유형의 요소와 특성 값을 만들 때 유용합니다. 다음 쿼리는 제품 모델 ID, 이름 및 해당 제품 모델에 속한 제품 목록을 검색합니다.

SELECT ProductModelID       as "@ProductModelID",
       Name                 as "@ProductModelName",
      (SELECT ProductID as "data()"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID = 
              Production.ProductModel.ProductModelID
      FOR XML PATH (''))    as "@ProductIDs"
FROM  Production.ProductModel
WHERE ProductModelID= 7 
FOR XML PATH('ProductModelData')

중첩 SELECT가 제품 ID 목록을 검색합니다. "data()"를 제품 ID에 대한 열 이름으로 지정합니다. PATH 모드에서는 행 요소 이름에 빈 문자열을 지정하므로 행 요소가 생성되지 않습니다. 대신 부모 SELECT의 <ProductModelData> 행 요소에 대한 ProductID 특성에 할당된 대로 값이 반환됩니다. 다음은 결과입니다.

<ProductModelData ProductModelID="7" 
                  ProductModelName="HL Touring Frame" 
                  ProductIDs="885 887 888 889 890 891 892 893" />

기본적으로 Null 값을 포함하는 열

기본적으로 열에 Null 값이 있으면 특성, 노드 또는 요소가 없습니다. 다음 쿼리에서와 같이 ELEMENTS 지시어를 사용하여 요소 중심 XML을 요청하고 NULL 값에 대해 요소 추가를 요청하도록 XSINIL을 지정하면 이 기본 동작을 덮어쓸 수 있습니다.

SELECT EmployeeID as "@EmpID", 
       FirstName  as "EmpName/First", 
       MiddleName as "EmpName/Middle", 
       LastName   as "EmpName/Last"
FROM   HumanResources.Employee E, Person.Contact C
WHERE  E.EmployeeID = C.ContactID
AND    E.EmployeeID=1
FOR XML PATH, ELEMENTS XSINIL

다음은 결과를 보여 줍니다. XSINIL을 지정하지 않으면 <Middle> 요소가 없습니다.

<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" EmpID="1">
  <EmpName>
    <First>Gustavo</First>
    <Middle xsi:nil="true" />
    <Last>Achong</Last>
  </EmpName>
</row>

네임스페이스 지원

이 릴리스에서는 WITH NAMESPACES를 사용하여 PATH 모드에 네임스페이스 지원을 제공합니다. 예를 들어 다음 쿼리에서는 후속 SELECT 문에 사용할 수 있는 네임스페이스("a:")를 선언할 WITH NAMESPACES 구문을 보여 줍니다.

WITH XMLNAMESPACES('a' as a)
SELECT 1 as 'a:b'
FOR XML PATH

다음 예제에서는 SELECT 쿼리에서 XML을 생성할 때 PATH 모드를 사용하는 방법을 보여 줍니다. 이러한 쿼리는 대부분 ProductModel 테이블의 Instructions 열에 저장된 자전거 제조 지침 XML 문서에 대해 지정됩니다. XML 지침에 대한 자세한 내용은 AdventureWorks 데이터베이스의 xml 데이터 형식 표시를 참조하십시오.

1. 간단한 PATH 모드 쿼리 지정

이 쿼리는 FOR XML PATH 모드를 지정합니다.

SELECT 
       ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH
go

다음 결과는 결과 행 집합의 각 열 값이 요소에 래핑되는 요소 중심 XML입니다. SELECT 절은 열 이름에 별칭을 지정하지 않으므로 생성된 자식 요소 이름은 SELECT 절에 있는 해당 열 이름과 같습니다. 행 집합의 각 행마다 <row> 태그가 추가됩니다.

<row>
  <ProductModelID>122</ProductModelID>
  <Name>All-Purpose Bike Stand</Name>
</row>
<row>
  <ProductModelID>119</ProductModelID>
  <Name>Bike Wash</Name>
</row>

다음 결과는 ELEMENTS 옵션이 지정된 RAW 모드 쿼리와 같습니다. 여기서는 결과 집합의 각 행에 대해 기본 <row> 요소가 있는 요소 중심 XML을 반환합니다.

SELECT ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML RAW, ELEMENTS

필요에 따라 행 요소 이름을 지정하여 기본 <row>를 덮어쓸 수 있습니다. 예를 들어 다음 쿼리는 행 집합의 각 행에 대해 <ProductModel> 요소를 반환합니다.

SELECT ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModel')
Go

결과 XML은 지정된 행 요소 이름을 갖습니다.

<ProductModel>
  <ProductModelID>122</ProductModelID>
  <Name>All-Purpose Bike Stand</Name>
</ProductModel>
<ProductModel>
  <ProductModelID>119</ProductModelID>
  <Name>Bike Wash</Name>
</ProductModel>

길이가 0인 문자열을 지정하면 래핑 요소가 생성되지 않습니다.

SELECT ProductModelID,
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('')
Go

다음은 결과입니다.

<ProductModelID>122</ProductModelID>
<Name>All-Purpose Bike Stand</Name>
<ProductModelID>119</ProductModelID>
<Name>Bike Wash</Name>

2. XPath 형식의 열 이름 지정

다음 쿼리에서 지정된 열 이름 ProductModelID는 '@'으로 시작하며 슬래시 기호('/')를 포함하지 않으므로 해당 열 값을 포함하는 <row> 요소의 특성이 결과 XML에 생성됩니다.

SELECT ProductModelID as "@id",
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModelData')
go

다음은 결과입니다.

< ProductModelData id="122">
    <Name>All-Purpose Bike Stand</Name>
</ ProductModelData >
< ProductModelData id="119">
    <Name>Bike Wash</Name>
</ ProductModelData >

FOR XML에 root 옵션을 지정하여 최상위 요소 하나를 추가할 수 있습니다.

SELECT ProductModelID as "@id",
       Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModelData'), root ('Root')
go

계층을 생성하려면 PATH 형식 구문을 포함합니다. 예를 들어 Name 열의 열 이름을 "SomeChild/ModelName"으로 변경하면 다음 결과와 같이 계층이 있는 XML이 생성됩니다.

<Root>
  <ProductModelData id="122">
    <SomeChild>
      <ModelName>All-Purpose Bike Stand</ModelName>
    </SomeChild>
  </ProductModelData>
  <ProductModelData id="119">
    <SomeChild>
      <ModelName>Bike Wash</ModelName>
    </SomeChild>
  </ProductModelData>
</Root>

다음 쿼리에서는 제품 모델 ID와 이름 외에 제품 모델의 제조 지침 위치를 검색합니다. Instructions 열은 xml 유형이므로 xml 데이터 유형의 query() 메서드를 지정하여 위치를 검색합니다.

SELECT ProductModelID as "@id",
       Name,
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
                /MI:root/MI:Location 
              ') as ManuInstr
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH ('ProductModelData'), root ('Root')
go

다음은 결과의 일부입니다. 쿼리에서 ManuInstr을 열 이름으로 지정하므로 query() 메서드가 반환한 XML이 다음과 같이 <ManuInstr> 태그에 래핑됩니다.

<Root>
  <ProductModelData id="7">
    <Name>HL Touring Frame</Name>
    <ManuInstr>
      <MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" 
        <MI:step>...</MI:step>...
      </MI:Location>
      ...
    </ManuInstr>
  </ProductModelData>
</Root>

이전 FOR XML 쿼리에 <Root> 및 <ProductModelData> 요소에 대한 네임스페이스를 포함하려고 할 수 있습니다. 먼저 WITH XMLNAMESPACES를 사용하여 네임스페이스 바인딩에 접두사를 정의하고 FOR XML 쿼리에 접두사를 사용하여 네임스페이스를 포함할 수 있습니다. 자세한 내용은 WITH XMLNAMESPACES를 사용하여 네임스페이스 추가를 참조하십시오.

WITH XMLNAMESPACES (
   'uri1' as ns1,  
   'uri2' as ns2,
   'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' as MI)
SELECT ProductModelID as "ns1:ProductModelID",
       Name           as "ns1:Name",
       Instructions.query('
                /MI:root/MI:Location 
              ') 
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH ('ns2:ProductInfo'), root('ns1:root')
go

WITH XMLNAMESPACES에는 MI 접두사도 정의됩니다. 그 결과로 지정된 xml 유형의 query() 메서드는 쿼리 프롤로그에 접두사를 정의하지 않습니다. 다음은 결과입니다.

<ns1:root xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" xmlns="uri2" xmlns:ns2="uri2" xmlns:ns1="uri1">
  <ns2:ProductInfo>
    <ns1:ProductModelID>7</ns1:ProductModelID>
    <ns1:Name>HL Touring Frame</ns1:Name>
    <MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" 
       LaborHours="2.5" LotSize="100" MachineHours="3" SetupHours="0.5" LocationID="10" >
       <MI:step>
          Insert <MI:material>aluminum sheet MS-2341</MI:material> into the <MI:tool>T-85A framing tool</MI:tool>. 
       </MI:step>
         ...
    </MI:Location>
     ...
  </ns2:ProductInfo>
</ns1:root>

3. PATH 모드를 사용하여 값 목록 생성

이 쿼리에서는 각 제품 모델에 대해 제품 ID의 값 목록을 생성하고 이 XML 조각에서와 같이 각 제품 ID에 대해 <ProductName> 중첩 요소를 생성합니다.

<ProductModelData ProductModelID="7" ProductModelName="..."  
                  ProductIDs="product id list in the product model" >
  <ProductName>...</ProductName>
  <ProductName>...</ProductName>
  ...
</ProductModelData>

다음은 필요한 XML을 생성하는 쿼리입니다.

SELECT ProductModelID     as "@ProductModelID",
       Name               as "@ProductModelName",
      (SELECT ProductID as "data()"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID = 
              Production.ProductModel.ProductModelID
       FOR XML PATH ('')) as "@ProductIDs",
       (SELECT Name as "ProductName"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID = 
              Production.ProductModel.ProductModelID
        FOR XML PATH ('')) as "ProductNames"
FROM   Production.ProductModel
WHERE  ProductModelID= 7 or ProductModelID=9
FOR XML PATH('ProductModelData')

이전 쿼리에서 다음을 유의하십시오.

  • 첫 번째 중첩 SELECT는 **data()**를 열 이름으로 사용하여 ProductID 목록을 반환합니다. 쿼리에서 빈 문자열을 FOR XML PATH의 행 요소 이름으로 지정하므로 요소가 생성되지 않습니다. 대신 값 목록이 ProductID 특성에 할당됩니다.
  • 두 번째 중첩 SELECT는 제품 모델에 속한 제품에 대해 제품 이름을 검색합니다. 쿼리에서 ProductName을 열 이름으로 지정하므로 <ProductNames> 요소에 래핑되어 반환되는 <ProductName> 요소를 생성합니다.

다음은 결과의 일부입니다.

<ProductModelData PId="7" 
                  ProductModelName="HL Touring Frame" 
                  ProductIDs="885 887 ...">
  <ProductNames>
    &lt;ProductName&gt;HL Touring Frame - Yellow, 60&lt;/ProductName&gt;
    &lt;ProductName&gt;HL Touring Frame - Yellow, 46&lt;/ProductName&gt;</ProductNames>
    ...
</ProductModelData>
<ProductModelData PId="9" 
                  ProductModelName="LL Road Frame" 
                  ProductIDs="722 723 724 ...">
  <ProductNames>
     &lt;ProductName&gt;LL Road Frame - Black, 58&lt;/ProductName&gt;
     &lt;ProductName&gt;LL Road Frame - Black, 60&lt;/ProductName&gt;
     &lt;ProductName&gt;LL Road Frame - Black, 62&lt;/ProductName&gt;
     ...
  </ProductNames>
</ProductModelData>

제품 이름을 생성하는 하위 쿼리가 올바르게 수정되어 XML에 추가된 문자열로 결과를 반환합니다. type 지시어 FOR XML PATH (''), type을 추가하면 하위 쿼리가 xml 유형으로 결과를 반환하며 수정되지 않습니다.

SELECT ProductModelID as "@ProductModelID",
      Name as "@ProductModelName",
      (SELECT ProductID as "data()"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID = 
              Production.ProductModel.ProductModelID
       FOR XML PATH ('')
       ) as "@ProductIDs",
       (
       SELECT Name as "ProductName"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID = 
              Production.ProductModel.ProductModelID
       FOR XML PATH (''), type
       ) as "ProductNames"
       
FROM Production.ProductModel
WHERE ProductModelID= 7 or ProductModelID=9
FOR XML PATH('ProductModelData')

4. 결과 XML에 네임스페이스 추가

WITH XMLNAMESPACES를 사용하여 네임스페이스 추가 항목에 설명된 대로 WITH XMLNAMESPACES를 사용하여 PATH 모드 쿼리에 네임스페이스를 포함시킬 수 있습니다. 예를 들어 SELECT 절에 지정된 이름에는 네임스페이스 접두사가 포함됩니다. 다음 PATH 모드 쿼리는 네임스페이스가 있는 XML을 생성합니다.

SELECT 'en'    as "English/@xml:lang",
       'food'  as "English",
       'ger'   as "German/@xml:lang",
       'Essen' as "German"
FOR XML PATH ('Translation')
go

<English> 요소에 추가된 @xml:lang 특성이 미리 정의된 xml 네임스페이스에 정의됩니다.

다음은 결과입니다.

<Translation>
  <English xml:lang="en">food</English>
  <German xml:lang="ger">Essen</German>
</Translation>

다음 쿼리는 WITH XMLNAMESPACES를 사용하여 XML 결과에 네임스페이스를 포함한다는 점을 제외하고 예 3과 비슷합니다. 자세한 내용은 WITH XMLNAMESPACES를 사용하여 네임스페이스 추가를 참조하십시오.

WITH XMLNAMESPACES ('uri1' as ns1,  DEFAULT 'uri2')
SELECT ProductModelID as "@ns1:ProductModelID",
      Name as "@ns1:ProductModelName",
      (SELECT ProductID as "data()"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID = 
              Production.ProductModel.ProductModelID
       FOR XML PATH ('')
       ) as "@ns1:ProductIDs",
       (
       SELECT ProductID as "@ns1:ProductID", 
              Name as "@ns1:ProductName"
       FROM   Production.Product
       WHERE  Production.Product.ProductModelID = 
              Production.ProductModel.ProductModelID
       FOR XML PATH , type 
       ) as "ns1:ProductNames"
       
FROM Production.ProductModel
WHERE ProductModelID= 7 or ProductModelID=9
FOR XML PATH('ProductModelData'), root('root')

다음은 결과입니다.

<root xmlns="uri2" xmlns:ns1="uri1">
  <ProductModelData ns1:ProductModelID="7" ns1:ProductModelName="HL Touring Frame" ns1:ProductIDs="885 887 888 889 890 891 892 893">
    <ns1:ProductNames>
      <row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="885" ns1:ProductName="HL Touring Frame - Yellow, 60" />
      <row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="887" ns1:ProductName="HL Touring Frame - Yellow, 46" />
       ...
    </ns1:ProductNames>
  </ProductModelData>
  <ProductModelData ns1:ProductModelID="9" ns1:ProductModelName="LL Road Frame" ns1:ProductIDs="722 723 724 725 726 727 728 729 730 736 737 738">
    <ns1:ProductNames>
      <row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="722" ns1:ProductName="LL Road Frame - Black, 58" />
        ...
    </ns1:ProductNames>
  </ProductModelData>
</root>

참고 항목

참조

FOR XML을 사용하는 XML 생성

개념

WITH XMLNAMESPACES를 사용하여 네임스페이스 추가

관련 자료

SELECT(Transact-SQL)

도움말 및 정보

SQL Server 2005 지원 받기