다음을 통해 공유


xml 데이터 형식 메서드 사용에 대한 지침

적용 대상: SQL ServerAzure SQL Database Azure SQL Managed Instance

이 항목에서는 xml 데이터 형식 메서드를 사용하기 위한 지침을 설명합니다.

PRINT 문

XML 데이터 형식 메서드는 다음 예제와 같이 PRINT 문에서 사용할 수 없습니다. xml 데이터 형식 메서드는 하위 쿼리로 처리되며 PRINT 문에는 하위 쿼리가 허용되지 않습니다. 결과적으로 다음 예제에서는 오류를 반환합니다.

DECLARE @x XML
SET @x = '<root>Hello</root>'
PRINT @x.value('/root[1]', 'varchar(20)') -- will not work because this is treated as a subquery (select top 1 col from table)

해결 방법은 먼저 value() 메서드의 결과를 xml 형식의 변수에 할당한 다음 쿼리에서 변수를 지정하는 것입니다.

DECLARE @x XML
DECLARE @c VARCHAR(max)
SET @x = '<root>Hello</root>'
SET @c = @x.value('/root[1]', 'VARCHAR(11)')
PRINT @c

GROUP BY 절

xml 데이터 형식 메서드는 내부적으로 하위 쿼리로 취급됩니다. GROUP BY에는 스칼라가 필요하고 집계 및 하위 쿼리가 허용되지 않기 때문에 GROUP BY 절에 xml 데이터 형식 메서드를 지정할 수 없습니다. 이에 대한 해결 방법은 절 내에서 XML 메서드를 사용하는 사용자 정의 함수를 호출하는 것입니다.

오류 보고

오류를 보고할 때 xml 데이터 형식 메서드는 다음 형식의 단일 오류를 발생시킵니다.

Msg errorNumber, Level levelNumber, State stateNumber:
XQuery [database.table.method]: description_of_error

예시:

Msg 2396, Level 16, State 1:
XQuery [xmldb_test.xmlcol.query()]: Attribute may not appear outside of an element

Singleton 검사

단일 항목이 필요한 위치 단계, 함수 매개 변수 및 연산자는 컴파일러가 런타임 시 단일 항목이 보장되는지 여부를 확인할 수 없는 경우 오류를 반환합니다. 이 문제는 형식화되지 않은 데이터에서 자주 발생합니다. 예를 들어 특성 조회에는 단일 부모 요소가 필요합니다. 단일 부모 노드를 선택하는 서수로 충분합니다. 특성 값 추출을 위한 node()-value() 조합의 평가에는 서수 사양이 필요하지 않을 수 있습니다. 다음 예제에 나와 있습니다.

예: 알려진 싱글톤

이 예제 에서 nodes() 메서드는 각 <book> 요소에 대해 별도의 행을 생성합니다. 노드에서 <book> 평가되는 value() 메서드는 특성인 @genre 값을 추출하고 싱글톤입니다.

SELECT nref.value('@genre', 'VARCHAR(max)') LastName
FROM T CROSS APPLY xCol.nodes('//book') AS R(nref)

XML 스키마는 형식화된 XML의 형식 검사에 사용됩니다. 노드가 XML 스키마에서 싱글톤으로 지정된 경우 컴파일러는 해당 정보를 사용하며 오류가 발생하지 않습니다. 그렇지 않으면 단일 노드를 선택하는 서수가 필요합니다. 특히 in과 같은 /book//title하위 축 또는 자체 축(//)을 사용하면 XML 스키마에서 지정하더라도 요소에 대한 <title> 단일 카디널리티 유추가 손실됩니다. 따라서 다시 작성 (/book//title)[1]해야 합니다.

유형 검사를 위해서는 //first-name[1](//first-name)[1] 간의 차이점을 인식해야 합니다. 전자는 각 노드가 형제 중 가장 <first-name> 왼쪽 노드인 노드 시퀀스를 <first-name> 반환합니다. 후자는 XML 인스턴스에서 문서 순서로 첫 번째 싱글톤 <first-name> 노드를 반환합니다.

예: 값 사용()

형식화되지 않은 XML 열에 대한 다음 쿼리는 정적 컴파일 오류를 발생합니다. value() 는 단일 노드를 첫 번째 인수로 예상하며 컴파일러는 런타임에 하나의 <last-name> 노드만 발생할지 여부를 결정할 수 없기 때문입니다.

SELECT xCol.value('//author/last-name', 'NVARCHAR(50)') LastName
FROM T

다음은 고려할 수 있는 해결 방법입니다.

SELECT xCol.value('//author/last-name[1]', 'NVARCHAR(50)') LastName
FROM T

그러나 이 솔루션은 각 XML 인스턴스에서 여러 <author> 노드가 발생할 수 있으므로 오류를 해결하지 않습니다. 다음 다시 쓰기가 작동합니다.

SELECT xCol.value('(//author/last-name/text())[1]', 'NVARCHAR(50)') LastName
FROM T

이 쿼리는 각 XML 인스턴스에서 첫 번째 <last-name> 요소의 값을 반환합니다.

참고 항목