XPath 데이터 형식(SQLXML 4.0)

Microsoft SQL Server, XPath 및 XSD(XML 스키마)의 데이터 형식은 각각 다릅니다. 예를 들어 XPath에는 정수나 날짜 데이터 형식이 없지만 SQL Server와 XSD에는 이러한 데이터 형식이 많습니다. XSD는 시간 값에 나노초 정밀도를 사용하지만 SQL Server에서는 최대 1/300초의 정밀도를 사용합니다. 따라서 한 데이터 형식을 다른 데이터 형식에 매핑할 수 없는 경우도 있습니다. SQL Server 데이터 형식을 XSD 데이터 형식에 매핑하는 방법은 데이터 형식 강제 변환 및 sql:datatype 주석(SQLXML 4.0)을 참조하십시오.

XPath에는 string, number 및 boolean의 세 가지 데이터 형식이 있습니다. number 데이터 형식은 항상 IEEE 754 배정밀도 부동 소수점입니다. SQL Server float(53) 데이터 형식이 XPath number와 가장 비슷합니다. 그러나 float(53)가 정확하게 IEEE 754와 같은 것은 아닙니다. 예를 들어 NaN(Not-a-Number)과 무한대는 모두 사용되지 않습니다. 따라서 숫자가 아닌 문자열을 number로 변환하고 0으로 나누려고 하면 오류가 발생합니다.

XPath 변환

OrderDetail[@UnitPrice > "10.0"] 같은 XPath 쿼리를 사용할 경우 암시적/명시적 데이터 형식 변환으로 인해 쿼리의 의미가 미세하게 변경될 수 있습니다. 따라서 XPath 데이터 형식의 구현 방법을 올바르게 이해하고 있어야 합니다. http://www.w3.org/TR/1999/PR-xpath-19991008.html의 W3C 웹 사이트에서 XPath 언어 사양 XML Path Language (XPath) version 1.0 W3C Proposed Recommendation 8 October 1999를 참조하십시오.

XPath 연산자는 다음의 네 범주로 나뉩니다.

  • 부울 연산자(and, or)

  • 관계형 연산자(<, >, <=, >=)

  • 같음 연산자(=, !=)

  • 산술 연산자(+, -, *, div, mod)

연산자 범주마다 해당 피연산자를 변환하는 방법이 다릅니다. XPath 연산자는 필요한 경우 피연산자를 암시적으로 변환합니다. 산술 연산자는 피연산자를 number로 변환하여 숫자 값을 반환합니다. 부울 연산자는 피연산자를 boolean으로 변환하여 부울 값을 반환합니다. 관계형 연산자와 같음 연산자는 부울 값을 반환합니다. 그러나 다음 표에서 볼 수 있듯이 피연산자의 원래 데이터 형식에 따라 서로 다른 변환 규칙이 적용됩니다.

피연산자

관계형 연산자

같음 연산자

두 피연산자가 모두 노드 집합입니다.

해당 string 값을 비교한 결과가 TRUE인 두 노드 중 하나는 첫 번째 집합에 있고 다른 하나는 두 번째 집합에 있는 경우에만 TRUE입니다.

같습니다.

하나는 노드 집합이고 다른 하나는 string입니다.

number로 변환되었을 때 number로 변환된 string과 비교한 결과가 TRUE인 노드가 노드 집합에 있는 경우에만 TRUE입니다.

string으로 변환되었을 때 string과 비교한 결과가 TRUE인 노드가 노드 집합에 있는 경우에만 TRUE입니다.

하나는 노드 집합이고 다른 하나는 number입니다.

number로 변환되었을 때 number와 비교한 결과가 TRUE인 노드가 노드 집합에 있는 경우에만 TRUE입니다.

같습니다.

하나는 노드 집합이고 다른 하나는 boolean입니다.

boolean으로 변환된 다음 number로 변환되었을 때 number로 변환된 boolean과 비교한 결과가 TRUE인 노드가 노드 집합에 있는 경우에만 TRUE입니다.

boolean으로 변환되었을 때 boolean과 비교한 결과가 TRUE인 노드가 노드 집합에 있는 경우에만 TRUE입니다.

둘 모두 노드 집합이 아닙니다.

두 피연산자를 모두 number로 변환한 다음 비교합니다.

두 피연산자를 모두 일반 형식으로 변환한 다음 비교합니다. 둘 중 하나가 boolean이면 boolean으로 변환하고 둘 중 하나가 number이면 number로 변환하며 그 외의 경우에는 string으로 변환합니다.

[!참고]

XPath 관계형 연산자는 항상 해당 피연산자를 number로 변환하므로 string 비교는 가능하지 않습니다. 날짜 비교를 포함하기 위해 SQL Server 2000에서는 XPath 사양에 대한 다음과 같은 변형을 제공합니다. 관계형 연산자가 string을 string과 비교하거나 노드 집합을 string과 비교하거나 문자열 값 노드 집합을 문자열 값 노드 집합과 비교하면 number 비교가 아닌 string 비교가 수행됩니다.

노드 집합 변환

노드 집합 변환이 항상 직관적이지는 않습니다. 노드 집합은 집합에 있는 첫 번째 노드의 문자열 값만 사용하여 string으로 변환됩니다. 노드 집합은 노드 집합이 string으로 변환된 다음 이 string이 다시 number로 변환되는 방법으로 number로 변환됩니다. 노드 집합은 해당 노드 집합의 존재 여부가 테스트되는 방식을 통해 boolean으로 변환됩니다.

[!참고]

SQL Server에서는 노드 집합에 대해 위치 선택을 수행하지 않습니다. 예를 들어 XPath 쿼리 Customer[3]는 세 번째 고객을 의미하는데 이러한 종류의 위치 선택이 SQL Server에서는 지원되지 않습니다. 따라서 XPath 사양에서 설명하는 노드 집합에서 string으로의 변환이나 노드 집합에서 number로의 변환이 구현되지 않습니다. SQL Server에서는 XPath 사양에 "첫 번째" 의미 체계가 지정된 경우 항상 "임의" 의미 체계를 사용합니다. 예를 들어 W3C XPath 사양을 따를 경우 XPath 쿼리 Order[OrderDetail/@UnitPrice > 10.0]는 UnitPrice가 10.0보다 큰 첫 번째 OrderDetail이 포함된 주문을 선택합니다. SQL Server에서는 이 XPath 쿼리가 UnitPrice가 10.0보다 큰 임의의 OrderDetail이 포함된 주문을 선택합니다.

boolean으로 변환될 때는 존재 테스트가 수행됩니다. 따라서 XPath 쿼리 Products[@Discontinued=true()]는 SQL 식 "Products.Discontinued = 1"이 아니라 SQL 식 "Products.Discontinued is not null"과 같습니다. 이 XPath 쿼리를 "Products.Discontinued = 1"과 같게 만들려면 먼저 노드 집합을 number와 같은 boolean이 아닌 형식으로 변환합니다. 예를 들면 Products[number(@Discontinued) = true()]와 같습니다.

대부분의 연산자는 노드 집합의 임의 노드 또는 특정 노드에 대해 TRUE이면 TRUE가 되도록 정의되어 있으므로 노드 집합이 비어 있으면 이러한 연산의 결과가 항상 FALSE입니다. 따라서 A가 비어 있으면 A = B와 A != B는 모두 FALSE이고 not(A=B)와 not(A!=B)는 TRUE입니다.

일반적으로 열에 매핑되는 특성이나 요소는 데이터베이스에서 해당 열 값이 null이 아닐 경우 존재합니다. 행에 매핑되는 요소는 행의 자식이 있는 경우에만 존재합니다.

[!참고]

is-constant라는 주석이 추가된 요소는 항상 존재합니다. 따라서 is-constant 요소에는 XPath 조건자를 사용할 수 없습니다.

노드 집합이 string이나 number로 변환될 경우 주석이 추가된 스키마에서 해당 XDR 유형(있는 경우)이 검사된 다음 이를 기반으로 필요한 변환이 결정됩니다.

XDR 데이터 형식을 XPath 데이터 형식에 매핑

다음 표에서와 같이 노드의 XPath 데이터 형식은 스키마의 XDR 데이터 형식에서 파생됩니다. EmployeeID 노드는 이해를 돕기 위한 목적으로 사용되었습니다.

XDR 데이터 형식

해당

XPath 데이터 형식

사용되는 SQL Server 변환

Nonebin.base64bin.hex

해당 사항 없음

NoneEmployeeID

boolean

boolean

CONVERT(bit, EmployeeID)

number, int, float,i1, i2, i4, i8,r4, r8ui1, ui2, ui4, ui8

number

CONVERT(float(53), EmployeeID)

id, idref, idrefsentity, entities, enumerationnotation, nmtoken, nmtokens, chardate, Timedate, Time.tz, string, uri, uuid

string

CONVERT(nvarchar(4000), EmployeeID, 126)

fixed14.4

해당 사항 없음(XPath에는 fixed14.4 XDR 데이터 형식에 해당하는 데이터 형식이 없음)

CONVERT(money, EmployeeID)

date

string

LEFT(CONVERT(nvarchar(4000), EmployeeID, 126), 10)

time

time.tz

string

SUBSTRING(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24)

날짜 및 시간 변환은 데이터베이스에 저장된 값이 SQL Server datetime 데이터 형식을 사용하든 string을 사용하든지 간에 수행됩니다. SQL Server datetime 데이터 형식은 timezone을 사용하지 않으며 XML time 데이터 형식보다 전체 자릿수가 적습니다. timezone 데이터 형식을 사용하거나 전체 자릿수를 늘리려면 string 형식을 사용하여 데이터를 SQL Server에 저장하십시오.

노드가 해당 XDR 데이터 형식에서 XPath 데이터 형식으로 변환될 때 한 XPath 데이터 형식에서 다른 XPath 데이터 형식으로의 추가 변환이 필요한 경우가 있습니다. 예를 들어 다음과 같은 XPath 쿼리를 살펴봅니다.

(@m + 3) = 4

@m이 fixed14.4 XDR 데이터 형식이면 XDR 데이터 형식에서 XPath 데이터 형식으로의 변환이 다음 구문을 사용하여 수행됩니다.

CONVERT(money, m)

이 변환에서는 노드 m이 fixed14.4에서 money로 변환됩니다. 그러나 값 3을 추가하려면 추가 변환이 필요합니다.

CONVERT(float(CONVERT(money, m))

이 XPath 식은 다음과 같이 계산됩니다.

CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)

다음 표에서 볼 수 있듯이 이 변환은 리터럴 또는 복합 식과 같은 다른 XPath 식에 적용되는 변환과 같습니다.

 

X는 알 수 없는 형식입니다.

X는 string입니다.

X는 number입니다.

X는 boolean입니다.

string(X)

CONVERT (nvarchar(4000), X, 126)

-

CONVERT (nvarchar(4000), X, 126)

CASE WHEN X THEN N'true' ELSE N'false' END

number(X)

CONVERT (float(53), X)

CONVERT (float(53), X)

-

CASE WHEN X THEN 1 ELSE 0 END

boolean(X)

-

LEN(X) > 0

X != 0

-

1.XPath 쿼리에서 데이터 형식 변환

주석이 추가된 XSD 스키마에 대해 지정된 다음 XPath 쿼리는 EmployeeID 특성 값이 E-1인 모든 Employee 노드를 선택합니다. 여기서 "E-"는 sql:id-prefix 주석을 사용하여 지정된 접두사입니다.

Employee[@EmployeeID="E-1"]

쿼리의 조건자는 다음 SQL 식과 같습니다.

N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'

EmployeeID가 XSD 스키마의 id(idref, idrefs, nmtoken, nmtokens 등) 데이터 형식 값 중 하나이므로 EmployeeID가 앞에서 설명한 변환 규칙을 사용하여 string XPath 데이터 형식으로 변환됩니다.

CONVERT(nvarchar(4000), Employees.EmployeeID, 126)

"E-" 접두사가 문자열에 추가된 다음 그 결과가 N'E-1'과 비교됩니다.

2.XPath 쿼리에서 몇 가지 데이터 형식 변환 수행

주석이 추가된 XSD 스키마에 대해 지정된 XPath 쿼리 을 살펴봅니다. OrderDetail[@UnitPrice * @OrderQty > 98]

이 XPath 쿼리는 조건자 @UnitPrice * @OrderQty > 98을 만족하는 모든 <OrderDetail> 요소를 반환합니다. 주석이 추가된 스키마에서 UnitPrice에 fixed14.4 데이터 형식이 주석으로 추가되어 있으면 이 조건자는 다음 SQL 식과 같습니다.

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) * CONVERT(float(53), OrderDetail.OrderQty) > CONVERT(float(53), 98)

XPath 쿼리에서 값 변환 시 첫 번째 변환에서는 XDR 데이터 형식을 XPath 데이터 형식으로 변환합니다. 앞의 표에 설명되어 있듯이 UnitPrice의 XSD 데이터 형식은 fixed14.4이므로 이것이 첫 번째로 사용되는 변환입니다.

CONVERT(money, OrderDetail.UnitPrice)) 

산술 연산자는 해당 피연산자를 number XPath 데이터 형식으로 변환하므로 값이 float(53)로 변환될 때 한 XPath 데이터 형식에서 다른 XPath 데이터 형식으로의 두 번째 변환이 적용됩니다. float(53)는 XPath number 데이터 형식과 비슷합니다.

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) 

OrderQty 특성에 XSD 데이터 형식이 없다고 가정할 경우 OrderQty가 한 번의 변환으로 number XPath 데이터 형식으로 변환됩니다.

CONVERT(float(53), OrderDetail.OrderQty)

마찬가지로 값 98은 number XPath 데이터 형식으로 변환됩니다.

CONVERT(float(53), 98)

[!참고]

스키마에 사용된 XSD 데이터 형식이 데이터베이스의 기본 SQL Server 데이터 형식과 호환되지 않거나 허용되지 않는 XPath 데이터 형식 변환이 수행되면 SQL Server에서 오류를 반환할 수 있습니다. 예를 들어 EmployeeID 특성에 id-prefix라는 주석이 추가되어 있으면 XPath Employee[@EmployeeID=1]에서 오류를 생성합니다. 이는 EmployeeID에 id-prefix라는 주석이 있어서 이를 number로 변환할 수 없기 때문입니다.