Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Область применения: SQL Server База данных SQL Azure
Microsoft SQL Server, XPath и XML Schema (XSD) имеют очень разные типы данных. Например, XPath не имеет целочисленных или датовых типов данных, но SQL Server и XSD имеют много. XSD использует точность nanosecond для значений времени, а SQL Server использует не более 1/300 секунд. Поэтому не всегда возможно сопоставить один тип другому. Дополнительные сведения о сопоставлении типов данных SQL Server с типами данных XSD см. в статьях "Приведение типов данных" и заметка sql:datatype (SQLXML 4.0).
XPath имеет три типа данных: string, number и boolean. Тип данных числа всегда является типом данных IEEE 754 двойной точности с плавающей запятой. Тип данных FLOAT(53) SQL Serverявляется ближайшим к номеру XPath. Однако float(53) не совсем IEEE 754. В частности, этот тип не содержит ни значения NaN (не число), ни значения бесконечности. Попытка преобразовать ненумерную строку в число и попытаться разделить на ноль приводит к ошибке.
Преобразования в XPath
При использовании запроса XPath, например, OrderDetail[@UnitPrice > "10.0"], явные и неявные преобразования типов данных могут различными неочевидными способами изменить значение запроса. Поэтому важно знать, как реализована система типов данных в XPath. Спецификация языка XPath, язык XML-пути (XPath) версии 1.0 W3C Предлагаемой рекомендации 8 октября 1999 г. можно найти на веб-сайте http://www.w3.org/TR/1999/PR-xpath-19991008.htmlW3C.
Операторы XPath делятся на четыре категории:
Логические операторы (и, или)
Реляционные операторы (<, ><=, =, >=)
Операторы равенства (=, !=)
Арифметические операторы (+, -, *, div, mod)
Операторы разных категорий по-разному преобразуют операнды. При необходимости операторы XPath неявно преобразуют операнды. Арифметические операторы преобразуют операнды в число и приводят к числовой величине. Логические операторы преобразуют операнды в логические и приводят к логическому значению. Результатом выполнения реляционных операторов и операторов равенства является логическое значение. Однако правила преобразования, которыми пользуются операторы, зависят от первоначальных типов операндов, как показано в таблице.
| Операнд | Реляционный оператор | Оператор равенства |
|---|---|---|
| Оба операнда представляют собой наборы узлов. | ЗНАЧЕНИЕ TRUE, если и только если в одном наборе есть узел и узел во втором наборе, чтобы сравнение их строковых значений было TRUE. | То же самое. |
| Один — это набор узлов, а другой — строка. | ЗНАЧЕНИЕ TRUE, если в наборе узлов есть узел, который при преобразовании в число, сравнение его со строкой, преобразованной в число, равно TRUE. | ЗНАЧЕНИЕ TRUE, если и только если в наборе узлов есть узел, который при преобразовании в строку сравнивается со строкой значение TRUE. |
| Один — это набор узлов, а другой — число. | ЗНАЧЕНИЕ TRUE, если и только если в наборе узлов есть узел, который при преобразовании в число, сравнение его с числом равно TRUE. | То же самое. |
| Один — это набор узлов, другой логический. | ЗНАЧЕНИЕ TRUE, если в наборе узлов есть узел, который при преобразовании в логический, а затем в число, сравнение этого узла с логическим преобразованным числом имеет значение TRUE. | True, если и только если в наборе узлов есть узел, который при преобразовании в логический, сравнение его с логическим значением имеет значение TRUE. |
| Ни один из них не представляет собой набор узлов. | Преобразуйте оба операнда в число , а затем сравните. | Преобразует оба операнда к одному типу, а затем сравнивает их. Преобразуйте влогическое значение, если одно из этих значений является логическим, числом, если это число; в противном случае преобразуется в строку. |
Примечание.
Поскольку реляционные операторы XPath всегда преобразовывают операнды в число, сравнение строк невозможно. Чтобы включить сравнения дат, SQL Server 2000 предлагает этот вариант спецификации XPath: когда реляционный оператор сравнивает строку со строкой, набор узлов со строкой или строковый набор узлов, заданный строкой, с набором строковых узлов, выполняется сравнение строк (не сравнение чисел).
Преобразования наборов узлов
Преобразования наборов узлов не всегда интуитивно понятны. Набор узлов преобразуется в строку, принимая строковое значение только первого узла в наборе. Набор узлов преобразуется в число , преобразовав его в строку, а затем преобразовав строку в число. Набор узлов преобразуется в логический , тестируя его существование.
Примечание.
SQL Server не выполняет позиционный выбор для наборов узлов: например, запрос Customer[3] XPath означает третьего клиента. Этот тип позиционного выбора не поддерживается в SQL Server. Таким образом, преобразования узлового набора в строку или числового набора узлов, как описано спецификацией XPath, не реализуются. SQL Server использует семантику "any" везде, где спецификация XPath указывает "первый" семантику. Например, на основе спецификации W3C XPath запрос Order[OrderDetail/@UnitPrice > 10.0] XPath выбирает эти заказы с первым OrderDetail , который имеет UnitPrice больше 10,0. В SQL Server этот запрос XPath выбирает эти заказы с любым OrderDetail , который имеет UnitPrice больше 10,0.
Преобразование в логическое значение создает тест существования; поэтому запрос Products[@Discontinued=true()] XPath эквивалентен выражению SQL Products.Discontinued не null, а не выражению SQL Products.Discontinued = 1. Чтобы сделать запрос эквивалентным последнему выражению SQL, сначала преобразуйте набор узлов в тип, отличный от логического типа, например число. Например, Products[number(@Discontinued) = true()].
Большинство операторов реализовано так, что они возвращают TRUE, если их результат равен TRUE хотя бы для одного (любого) узла набора, поэтому они возвращают FALSE, если набор узлов пуст. Таким образом, если набор узлов A пуст, оба оператора A = B и A != B вернут FALSE, а not(A=B) и not(A!=B) — TRUE.
Как правило, атрибут или элемент, сопоставленный со столбцом, существует, если значение этого столбца в базе данных не равно NULL. Элементы, сопоставляемые со строками, существуют, если есть хотя бы один из их дочерних элементов.
Примечание.
Элементы, аннотированные с константой , всегда существуют. Следовательно, предикаты XPath нельзя использовать для элементов константы .
При преобразовании набора узлов в строку или число его тип 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 | строка | CONVERT(nvarchar(4000), EmployeeID, 126) |
| fixed14.4 | н/д (в XPath нет типа данных, эквивалентного типу fixed14.4 XDR) | CONVERT(деньги, EmployeeID) |
| Дата | строка | LEFT(CONVERT(nvarchar(4000), EmployeeID, 126), 10) |
| Время time.tz |
строка | ПОДСТРОКА(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24) |
Преобразования даты и времени предназначены для работы, хранится ли значение в базе данных с помощью типа данных даты и времени SQL Serverили строки. Обратите внимание, что тип данных даты и времени SQL Serverне использует часовой пояс и имеет меньшую точность, чем тип данных времени XML. Чтобы включить тип данных часового пояса или дополнительную точность, сохраните данные в SQL Server с помощью строкового типа.
При преобразовании узла из типа данных XDR в тип данных XPath иногда требуются дополнительные преобразования (из одного типа XPath в другой тип XPath). В качестве примера рассмотрим следующий запрос XPath:
(@m + 3) = 4
Если @m тип данных XDR имеет фиксированный 14.4 , преобразование из типа данных XDR в тип данных XPath выполняется с помощью:
CONVERT(money, m)
В этом преобразовании узел преобразуется из m в деньги. Однако для прибавления 3 требуется дополнительное преобразование:
CONVERT(float(CONVERT(money, m))
Выражение XPath вычисляется следующим образом:
CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)
Как показано в следующей таблице, это то же самое преобразование, которое применялось для других выражений XPath (например, литералов или составных выражений).
| Х неизвестен | X — строка | X — число | X является логическим | |
|---|---|---|---|---|
| string(X) | CONVERT (nvarchar(4000), X, 126) | - | CONVERT (nvarchar(4000), X, 126) | СЛУЧАЙ, КОГДА X THEN N'true' ELSE N'false' КОНЕЦ |
| number(X) | CONVERT (float(53), X) | CONVERT (float(53), X) | - | СЛУЧАЙ, КОГДА X И 1 ELSE 0 ЗАКАНЧИВАЮТСЯ |
| boolean(X) | - | LEN(X) > 0 | X != 0 | - |
Примеры
А. Преобразование типа данных в запросе XPath
В следующем запросе XPath, указанном для аннотированной схемы XSD, запрос выбирает все узлы EmployeeID со значением атрибута EmployeeID E-1, где "E-" является префиксом, указанным с помощью заметки sql:id-префикса .
Employee[@EmployeeID="E-1"]
Предикат в запросе эквивалентен следующему выражению SQL:
N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'
Так как EmployeeID является одним из значений типа данных типа данных XSD (idref, idrefs, nmtokens, nmtokens и т. д.) в схеме XSD, EmployeeID преобразуется в строковый тип данных XPath с помощью описанных ранее правил преобразования.
CONVERT(nvarchar(4000), Employees.EmployeeID, 126)
К строке добавляется префикс «E-», а результат затем сравнивается с N'E-1'.
B. Несколько преобразований типов данных в запросе XPath
Рассмотрим этот запрос XPath, указанный для аннотированной схемы XSD: OrderDetail[@UnitPrice * @OrderQty > 98]
Этот запрос XPath возвращает все >, удовлетворяющие предикату.@UnitPrice * @OrderQty > 98
Если модуль UnitPrice аннотирован с типом данных fixed14.4 в аннотированной схеме, этот предикат эквивалентен выражению SQL:
CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) * CONVERT(float(53), OrderDetail.OrderQty) > CONVERT(float(53), 98)
В ходе преобразований значений в запросе XPath сначала тип данных XDR преобразуется в тип данных XPath. Так как тип данных XSD UnitPriceисправлено14.4, как описано в предыдущей таблице, это первое преобразование, которое используется:
CONVERT(money, OrderDetail.UnitPrice))
Так как арифметические операторы преобразуют операнды в тип данных XPath, второе преобразование (из одного типа данных XPath в другой тип данных XPath) применяется, в котором значение преобразуется в float(53) (float(53) близко к типу данных номера XPath):
CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice))
Если атрибут OrderQty не имеет типа данных XSD, OrderQty преобразуется в число типов данных XPath в одном преобразовании:
CONVERT(float(53), OrderDetail.OrderQty)
Аналогичным образом значение 98 преобразуется в тип данных XPath:
CONVERT(float(53), 98)
Примечание.
Если тип данных XSD, используемый в схеме, несовместим с базовым типом данных SQL Server в базе данных или если выполняется невозможное преобразование типов данных XPath, SQL Server может вернуть ошибку. Например, если атрибут EmployeeID аннотирован с заметкой идентификатора префикса, XPath создает ошибку, так как Employee[@EmployeeID=1] имеет заметку с идентификатором префикса и не может быть преобразован в число.