nodes() 메서드(xml 데이터 형식)

적용 대상:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

nodes() 메서드는 xml 데이터 형식 인스턴스를 관계형 데이터로 조각화하려는 경우에 유용합니다. 이를 통해 새 행에 매핑될 노드를 식별할 수 있습니다.

모든 xml 데이터 형식 인스턴스에는 암시적으로 제공된 컨텍스트 노드가 있습니다. 열 또는 변수에 저장된 XML 인스턴스의 경우 이 노드는 문서 노드입니다. 문서 노드는 모든 xml 데이터 형식 인스턴스의 맨 위에 있는 암시적 노드입니다.

nodes() 메서드의 결과는 원래 XML 인스턴스의 논리적 복사본을 포함하는 행 집합입니다. 이러한 논리 복사본에서 모든 행 인스턴스의 컨텍스트 노드는 쿼리 식으로 식별되는 노드 중 하나로 설정됩니다. 이 방식으로, 이후 쿼리는 이 컨텍스트 노드에 상대적으로 검색할 수 있습니다.

행 집합에서 여러 값을 검색할 수 있습니다. 예를 들어 nodes()에 의해 반환된 행 집합에 value() 메서드를 적용하고 원래 XML 인스턴스에서 여러 값을 검색할 수 있습니다. XML 인스턴스에 적용된 경우 value() 메서드는 값을 하나만 반환합니다.

Syntax

nodes (XQuery) as Table(Column)  

참고 항목

SQL Server 2014(12.x) 및 이전 버전에 대한 Transact-SQL 구문을 보려면 이전 버전 설명서를 참조 하세요.

인수

XQuery
문자열 리터럴, XQuery 식입니다. 쿼리 식이 노드를 생성하는 경우 생성된 이러한 노드는 결과 행 집합에 노출됩니다. 쿼리 식이 빈 시퀀스로 생성되면 행 집합도 비어 있습니다. 쿼리 식이 노드 대신 원자 값이 들어 있는 시퀀스를 정적으로 생성하는 경우 정적 오류가 발생합니다.

Table(Column)
결과 행 집합의 테이블 이름 및 열 이름입니다.

설명

예를 들어 다음 표가 있다고 가정합니다.

T (ProductModelID INT, Instructions XML)  

다음 제조 지침 문서가 이 테이블에 저장되어 있고 조각만 표시됩니다. 문서에는 세 개의 제조 위치가 있습니다.

<root>  
  <Location LocationID="10"...>  
     <step>...</step>  
     <step>...</step>  
      ...  
  </Location>  
  <Location LocationID="20" ...>  
       ...  
  </Location>  
  <Location LocationID="30" ...>  
       ...  
  </Location>  
</root>  

nodes() 쿼리 식을 /root/Location 사용하는 메서드 호출은 각각 원래 XML 문서의 논리적 복사본을 포함하고 컨텍스트 항목이 노드 중 <Location> 하나로 설정된 세 개의 행이 있는 행 집합을 반환합니다.

Product  
ModelID      Instructions  
----------------------------------  
1      <root><Location LocationID="10" ... />  
             <Location LocationID="20" ... />  
             <Location LocationID="30" .../></root>  
1      <root><Location LocationID="10" ... />  
             <Location LocationID="20" ... />  
             <Location LocationID="30" .../></root>  
1      <root><Location LocationID="10" ... />  
             <Location LocationID="20" ... />  
             <Location LocationID="30" .../></root>  

그런 다음, xml 데이터 형식 메서드를 사용하여 이 행 집합을 쿼리할 수 있습니다. 다음 쿼리는 생성된 각 행에 대한 컨텍스트 항목의 하위 트리를 추출합니다.

SELECT T2.Loc.query('.')  
FROM T  
CROSS APPLY Instructions.nodes('/root/Location') AS T2(Loc)   

결과는 다음과 같습니다.

ProductModelID  Instructions  
----------------------------------  
1        <Location LocationID="10" ... />  
1        <Location LocationID="20" ... />  
1        <Location LocationID="30" .../>  

반환된 행 집합이 형식 정보를 기본. query(), value(), exist(), nodes()와 같은 xml 데이터 형식 메서드를 nodes() 메서드의 결과에 적용할 수 있습니다. 그러나 XML 인스턴스를 수정하기 위해 modify() 메서드를 적용할 수는 없습니다.

또한 행 집합의 컨텍스트 노드는 구체화할 수 없습니다. 즉, SELECT 문에는 사용할 수 없습니다. 그러나 IS NULL 및 COUNT(*)에서 사용할 수 있습니다.

nodes() 메서드를 사용하는 시나리오는 XML의 행 집합 뷰를 제공하는 OPENXML(Transact-SQL)을 사용하는 시나리오와 동일합니다. 그러나 여러 행의 XML 문서가 포함된 테이블에서 nodes() 메서드를 사용할 때는 커서를 사용할 필요가 없습니다.

nodes() 메서드에서 반환되는 행 집합은 명명되지 않은 행 집합입니다. 따라서 별칭을 사용하여 명시적으로 이름을 지정해야 합니다.

nodes() 함수는 사용자 정의 함수의 결과에 직접 적용할 수 없습니다. 스칼라 사용자 정의 함수의 결과와 함께 nodes() 함수를 사용하려면 다음 중 하나를 수행하면 됩니다.

  • 변수에 사용자 정의 함수의 결과 할당
  • 파생 테이블을 사용하여 사용자 정의 함수 반환 값에 열 별칭을 할당한 후 CROSS APPLY를 사용하여 별칭에서 선택

다음 예에서는 CROSS APPLY를 사용하여 사용자 정의 함수의 결과에서 선택하는 한 가지 방법을 보여 줍니다.

USE AdventureWorks;  
GO  
  
CREATE FUNCTION XTest()  
RETURNS XML  
AS  
BEGIN  
RETURN '<document/>';  
END;  
GO  
  
SELECT A2.B.query('.')  
FROM  
(SELECT dbo.XTest()) AS A1(X)   
CROSS APPLY X.nodes('.') A2(B);  
GO  
  
DROP FUNCTION XTest;  
GO  

예제

xml 형식의 변수에 대해 nodes() 메서드 사용

다음 예에는 <Root> 최상위 요소 하나와 <row> 자식 요소 3개가 있는 XML 문서가 있습니다. 이 쿼리는 nodes() 메서드를 사용하여 각 <row> 요소에 대해 하나의 개별 컨텍스트 노드를 설정합니다. nodes() 메서드는 3개의 행이 포함된 행 집합을 반환합니다. 각 행에는 원래 문서에서 서로 다른 <row> 요소를 식별하는 각 컨텍스트 노드와 함께 원래 XML의 논리적 복사본이 들어 있습니다.

그런 다음 쿼리는 각 행에서 컨텍스트 노드를 반환합니다.

DECLARE @x XML   
SET @x='<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>'  
SELECT T.c.query('.') AS result  
FROM   @x.nodes('/Root/row') T(c)  
GO  

다음 예의 결과에서 쿼리 메서드는 컨텍스트 항목과 해당 내용을 반환합니다.

<row id="1"><name>Larry</name><oflw>some text</oflw></row>  
<row id="2"><name>moe</name></row>  
<row id="3"/>  

컨텍스트 노드에 부모 접근자를 적용하면 3개 모두에 대한 <Root> 요소를 반환합니다.

SELECT T.c.query('..') AS result  
FROM   @x.nodes('/Root/row') T(c)  
GO  

결과는 다음과 같습니다.

<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  
<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  
<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  

xml 형식의 열에 대해 nodes() 메서드 지정

자전거 제조 지침은 이 예제에서 사용되며 ProductModel 테이블의 Instructions xml 형식 열에 저장됩니다.

다음 예제에서는 테이블의 nodes()xml 형식 열에 Instructions 대해 메서드를 ProductModel 지정합니다.

nodes() 메서드는 /MI:root/MI:Location 경로를 지정하여 <Location> 요소를 컨텍스트 노드로 설정합니다. 결과 행 집합에는 <Location> 요소로 설정된 컨텍스트 노드와 함께 문서에 있는 각 <Location> 노드에 대해 원래 문서의 논리적 복사본이 하나씩 들어 있습니다. 따라서 nodes() 함수는 일련의 <Location> 컨텍스트 노드를 제공합니다.

이 행 집합에 대한 query() 메서드는 self::node를 요청하고 각 행에 <Location> 요소를 반환합니다.

이 예에서 쿼리는 특정 제품 모델의 제조 지침 문서에 각 <Location> 요소를 컨텍스트 노드로 설정합니다. 이러한 컨텍스트 노드를 사용하여 다음과 같은 값을 검색할 수 있습니다.

  • 각 <Location>에서 위치 ID 찾기

  • 각 <Location>에서 제조 단계(<step> 자식 요소) 검색

이 쿼리는 메서드에서 약어 구문 '.'self::node() 이 지정된 query() 컨텍스트 항목을 반환합니다.

다음을 참고하십시오.

  • nodes() 메서드는 Instructions 열에 적용되고 행 집합 T (C)을 반환합니다. 이 행 집합에는 컨텍스트 항목으로 /root/Location이 포함된 원래 제조 지침 문서의 논리적 복사본이 포함됩니다.

  • CROSS APPLY는 nodes() 테이블의 각 행에 ProductModel를 적용하고 결과 집합을 생성하는 행만 반환합니다.

    SELECT C.query('.') as result  
    FROM Production.ProductModel  
    CROSS APPLY Instructions.nodes('  
    declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
    /MI:root/MI:Location') as T(C)  
    WHERE ProductModelID=7  
    

    다음은 부분 결과입니다.

    <MI:Location LocationID="10"  ...>  
       <MI:step ... />  
          ...  
    </MI:Location>  
    <MI:Location LocationID="20"  ... >  
        <MI:step ... />  
          ...  
    </MI:Location>  
    ...  
    

다른 nodes() 메서드에서 반환된 행 집합에 nodes() 적용

다음 코드는 테이블 열 ProductModel 의 제조 지침에 Instructions 대한 XML 문서를 쿼리합니다. 이 쿼리는 제품 모델 ID, 제조 위치 및 제조 단계를 포함하는 행 집합을 반환합니다.

다음을 참고하십시오.

  • nodes() 메서드는 열에 Instructions 적용되고 행 집합을 반환합니다 T1 (Locations) . 이 행 집합에는 요소가 항목 컨텍스트로 포함된 원래 제조 지침 문서의 /root/Location 논리적 복사본이 포함됩니다.

  • nodes() 은 행 집합에 T1 (Locations) 적용되고 행 집합을 반환합니다 T2 (steps) . 이 행 집합에는 요소가 항목 컨텍스트로 포함된 원래 제조 지침 문서의 /root/Location/step 논리적 복사본이 포함됩니다.

SELECT ProductModelID, Locations.value('./@LocationID','int') AS LocID,  
steps.query('.') AS Step         
FROM Production.ProductModel         
CROSS APPLY Instructions.nodes('         
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
/MI:root/MI:Location') AS T1(Locations)         
CROSS APPLY T1.Locations.nodes('         
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
./MI:step ') AS T2(steps)         
WHERE ProductModelID=7         
GO         

결과는 다음과 같습니다.

ProductModelID LocID Step         
----------------------------         
7      10   <step ... />         
7      10   <step ... />         
...         
7      20   <step ... />         
7      20   <step ... />         
7      20   <step ... />         
...         

쿼리는 접두사를 MI 두 번 선언합니다. 대신 접두사를 한 번 선언하고 쿼리에서 사용할 수 있습니다 WITH XMLNAMESPACES .

WITH XMLNAMESPACES (  
   'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' AS MI)  
  
SELECT ProductModelID, Locations.value('./@LocationID','int') AS LocID,  
steps.query('.') AS Step         
FROM Production.ProductModel         
CROSS APPLY Instructions.nodes('         
/MI:root/MI:Location') AS T1(Locations)         
CROSS APPLY T1.Locations.nodes('         
./MI:step ') as T2(steps)         
WHERE ProductModelID=7         
GO    

참고 항목

WITH XMLNAMESPACES를 사용하여 쿼리에 네임스페이스 추가
XML 데이터의 인스턴스 만들기
xml 데이터 형식 메서드