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

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

XML에 대해 XQuery를 수행하고 SQL 형식의 값을 반환합니다. 이 메서드는 스칼라 값을 반환합니다.

일반적으로 이 메서드를 사용하여 xml 형식 열, 매개 변수 또는 변수에 저장된 XML 인스턴스에서 값을 추출합니다. 이러한 방식으로 XML 데이터를 비 XML 열의 데이터와 결합하거나 비교하는 쿼리를 지정할 SELECT 수 있습니다.

Syntax

value ( XQuery , SQLType )

참고 항목

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

인수

XQuery

XML 인스턴스 내의 데이터를 검색하는 문자열 리터럴인 XQuery 식입니다. XQuery는 최대 하나의 값을 반환해야 합니다. 그렇지 않으면 오류가 반환됩니다.

SQLType

반환할 기본 설정 SQL 형식인 문자열 리터럴입니다. 이 메서드의 반환 형식은 SQLType 매개 변수와 일치합니다. SQLType은 xml 데이터 형식, CLR(공용 언어 런타임) 사용자 정의 형식, 이미지, 텍스트, ntext 또는 sql_variant 데이터 형식일 수 없습니다. SQLType 은 사용자 정의 SQL 데이터 형식일 수 있습니다.

이 메서드는 value() Transact-SQL CONVERT 연산자를 암시적으로 사용합니다. value() 에서는 직렬화된 문자열 표현인 XQuery 식의 결과를 XSD(XML 스키마 정의) 형식에서 Transact-SQL 변환으로 지정된 해당 SQL 형식으로 변환하려고 합니다. 형식 캐스팅 규칙에 대한 CONVERT자세한 내용은 CAST 및 CONVERT를 참조 하세요.

성능상의 이유로 조건자의 메서드를 사용하는 value() 대신 관계형 값과 비교할 수 있습니다.exist()sql:column()exist() 예제는 이 문서의 뒷부분에 나와 있습니다.

예제

이 글은 AdventureWorks2022샘플 데이터터베이스를 필요로 하며, 이는 Microsoft SQL Server 예제 및 커뮤니티 프로젝트(Microsoft SQL Server Samples and Community Projects) 홈 페이지에서 다운로드할 수 있습니다.

A. XML 형식 변수에 대해 value() 메서드 사용

다음 예제에서는 XML 인스턴스가 xml 형식의 변수에 저장됩니다. value() 메서드는 XML에서 ProductID 특성 값을 검색합니다. 그러면 값이 int 변수에 할당됩니다.

DECLARE @myDoc XML;
DECLARE @ProdID INT;

SET @myDoc = '<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>
  <Warranty>1 year parts and labor</Warranty>
  <Maintenance>3 year parts and labor extended maintenance is available</Maintenance>
</Features>
</ProductDescription>
</Root>';

SET @ProdID = @myDoc.value('(/Root/ProductDescription/@ProductID)[1]', 'int');
SELECT @ProdID;

1 값이 결과로 반환됩니다.

XML 인스턴스에는 특성이 하나 ProductID 뿐이지만 정적 입력 규칙을 사용하려면 경로 식이 싱글톤을 반환하도록 명시적으로 지정해야 합니다. 따라서 [1] 경로 식의 끝에 추가됩니다. 정적 입력에 대한 자세한 내용은 XQuery 및 정적 입력을 참조 하세요.

B. value() 메서드를 사용하여 XML 형식 열에서 값 검색

다음 쿼리는 데이터베이스의 xml 형식 열(CatalogDescription)에 AdventureWorks2022 대해 지정됩니다. 쿼리는 열에 ProductModelID 저장된 각 XML 인스턴스에서 특성 값을 검색합니다.

SELECT CatalogDescription.value(
    'declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
       (/PD:ProductDescription/@ProductModelID)[1]', 'int') AS Result
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL
ORDER BY Result DESC;

이전 쿼리의 참고 사항:

  • namespace 키워드(keyword) 네임스페이스 접두사를 정의하는 데 사용됩니다.

  • 정적 입력 요구 사항에 따라 [1] 경로 식 value() 이 싱글톤을 반환함을 명시적으로 나타내기 위해 메서드의 경로 식 끝에 추가됩니다.

다음은 부분 결과입니다.

35
34
...

C. value() 및 exist() 메서드를 사용하여 XML 형식 열에서 값을 검색합니다.

다음 예제에서는 xml 데이터 형식의 value()메서드와 exist() 메서드를 모두 사용하는 방법을 보여 줍니다. 이 value() 메서드는 XML에서 특성 값을 검색 ProductModelID 하는 데 사용됩니다. exist() 절에 있는 WHERE 메서드는 테이블의 행을 필터링하는 데 사용됩니다.

이 쿼리는 여러 기능 중 하나로 보증 정보(<Warranty> 요소)가 포함된 제품 모델 ID를 XML 인스턴스로부터 검색합니다. WHERE 절의 조건에서는 exist() 메서드를 사용하여 이 조건을 만족하는 행만 검색합니다.

SELECT CatalogDescription.value(
    'declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
           (/PD:ProductDescription/@ProductModelID)[1]', 'int') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist(
    'declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     declare namespace wm="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";

     /PD:ProductDescription/PD:Features/wm:Warranty') = 1;

이전 쿼리의 참고 사항:

  • 열은 CatalogDescription 형식화된 XML 열입니다. 즉, 연결된 스키마 컬렉션이 있습니다. 모듈 및 프롤로그 - XQuery 프롤로그에서 네임스페이스 선언은 쿼리 본문의 뒷부분에서 사용되는 접두사를 정의하는 데 사용됩니다.

  • 메서드가 exist() 반환 1 되는 경우(true), XML 인스턴스에 자식 요소가 기능 중 하나로 포함 <Warranty> 됨을 나타냅니다.

  • 그런 다음 절의 SELECT 메서드는 value() 특성 값을 정수로 검색 ProductModelID 합니다.

다음은 부분 결과입니다.

19
23
...

D. value() 메서드 대신 exist() 메서드 사용

성능상의 이유로 조건자에서 value() 메서드를 사용하여 관계형 값과 비교하는 대신 exist()에서 sql:column()를 사용하세요. 예시:

CREATE TABLE T (c1 INT, c2 VARCHAR(10), c3 XML);
GO

SELECT c1, c2, c3
FROM T
WHERE c3.value('(/root/@a)[1]', 'integer') = c1;
GO

이 코드는 다음과 같이 다시 작성할 수 있습니다.

SELECT c1, c2, c3
FROM T
WHERE c3.exist('/root[@a=sql:column("c1")]') = 1;
GO