Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 XQuery выборочно работает с большими числами  [new]
blackout
Member

Откуда:
Сообщений: 37
Добрый день.
Внезапно наткнулись на странное поведение xquery. Запрос вида
DECLARE 
	@num	NUMERIC(18, 0)
	,@x     XML

SET @x = '<r a="' + CAST(@num AS VARCHAR(18)) + '" />'

SELECT @num, @x.exist('/r[@a=sql:variable("@num")]')

Для трех разных @num возвращает разные значения:
472999999999	1
473000000000	0
473000000001	1

Начинает корректно работать только при изменении инструкции на
@x.exist('/r[string(@a)=string(sql:variable("@num"))]')
Но за много лет понаписано столько всего и с exist() и с value() и с nodes(), а тут такие новости. Неужто всё перелопачивать придется?
XPATH 1.0 и 2.0 отрабатывают на примере корректно, использование sql:variable необязательно, сбоит и при явном указании цифры.
12 ноя 13, 16:37    [15116609]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Откуда он тип знает?
DECLARE	@num	Numeric(18,0) = 473000000000
DECLARE	@xml	XML = (SELECT @num AS [@a] FOR XML Path('r'),Type)

SELECT @num, @xml.exist('/r[xs:decimal(@a)=sql:variable("@num")]')
4730000000001
12 ноя 13, 21:40    [15118106]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
blackout
SET @x = '<r a="' + CAST(@num AS VARCHAR(18)) + '" />'
За такое вешают за одно место.
12 ноя 13, 21:41    [15118110]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
blackout
Member

Откуда:
Сообщений: 37
Mnior
Откуда он тип знает?
DECLARE	@num	Numeric(18,0) = 473000000000

а откуда он для 472999999999 или для 473000000001 тип знает?
То, что работает при явном приведении типов, я и так знал и написал в вопросе.
12 ноя 13, 22:04    [15118166]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
SandalTree
Member

Откуда: Перехлёсток восьми батог
Сообщений: 28146
Mnior
blackout
SET @x = '<r a="' + CAST(@num AS VARCHAR(18)) + '" />'
За такое вешают за одно место.
А в чём дело?

До волшебной цифры 922337205 работает как часы.

ТЫ знаешь почему?

Мне просто интересно.
12 ноя 13, 22:06    [15118170]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
blackout
Member

Откуда:
Сообщений: 37
Mnior
blackout
SET @x = '<r a="' + CAST(@num AS VARCHAR(18)) + '" />'
За такое вешают за одно место.
Каюсь, найденная фича затмила разум)
12 ноя 13, 22:22    [15118231]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Да я тоже не пойму пока. Правила приведения типов в запросах XQuery
12 ноя 13, 23:34    [15118549]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3422
blackout,

declare @num numeric(20,3)= 473000000000, @x xml;

set @x = (
	select @num as [@a] for xml path('r'), type
);

select @x, @num, @x.exist('/r[xs:decimal(@a) = sql:variable("@num")]');
Как-то тоже сталкивался с тем, что XQuery бигинты не понимает, еще на 2005. Не помню уже, как решил, скорее всего создавал отдельную переменную строкового типа и по ней искал.
13 ноя 13, 04:15    [15119044]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
SandalTree
Member

Откуда: Перехлёсток восьми батог
Сообщений: 28146
Mnior
Да я тоже не пойму пока. Правила приведения типов в запросах XQuery
Блин, там целый мир. Чувствую себя ребёнком.
13 ноя 13, 04:26    [15119049]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
blackout
Member

Откуда:
Сообщений: 37
Ennor Tiegael
XQuery бигинты не понимает

Так ведь не понимает выборочно! одно прокатывает, второе нет. Причем ладно бы там выход за пределы максимального значения для decimal или еще что-нибудь более-или-менее очевидное, но нет, среди трех чисел два нормально, а третье, между двумя нормальными, нет. Можно было бы прицепиться, что не работает на том, которое с ноликами в конце, но нет, например, с 17303995612076 возвращает 1, а уже 17303995612077 - 0, потом еще какое-нибудь число больше этих - снова будет возвращать 1. Как-то это криво выглядит. Если вам нужно явное приведение типа, то сделайте так, чтобы без оного не работало ни с единицей, ни с пятёркой, ни с триллионом, или на крайняк пусть хоть сваливается с ошибкой.
С вариантами решения тут особо не развернешься - шерстить код и в xquery явно указывать типы
13 ноя 13, 09:59    [15119465]     Ответить | Цитировать Сообщить модератору
 Re: XQuery выборочно работает с большими числами  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
blackout
XPATH 1.0 и 2.0 отрабатывают на примере корректно, использование sql:variable необязательно, сбоит и при явном указании цифры.
Есть повод зарегать как БАГ.
Ибо по описалову должно работать. Видно что он заранее приводит к какому-то промежуточному неявному неизвестному типу в зависимости от значений (как моча в голову ударит). Хотя по доке должно быть явно к неявному xdt:AnyAtomicType.
+
DECLARE	@x	XML		= '<r a="473000000000" />'
DECLARE	@n	NVarChar(20)	=       '473000000000'
,	@s	Numeric(36,2)	=        473000000000

SELECT	@x.exist('/r[@a=sql:variable("@n")]')
,	@x.exist('/r[@a=sql:variable("@s")]')
,	@x.exist('/r[@a=xs:hexBinary(sql:variable("@n"))]')
,	@x.exist('/r[@a=xs:string   (sql:variable("@n"))]')
,	@x.exist('/r[@a=xs:NMTOKEN  (sql:variable("@n"))]')
,	@x.exist('/r[@a=xs:anyURI   (sql:variable("@n"))]')
GO
DECLARE	@x	XML		= '<r a="473000000001" />'
DECLARE	@n	NVarChar(20)	=       '473000000001'
,	@s	Numeric(36,2)	=        473000000001

SELECT	@x.exist('/r[@a=sql:variable("@n")]')
,	@x.exist('/r[@a=sql:variable("@s")]')
,	@x.exist('/r[@a=xs:hexBinary(sql:variable("@n"))]')
,	@x.exist('/r[@a=xs:string   (sql:variable("@n"))]')
,	@x.exist('/r[@a=xs:NMTOKEN  (sql:variable("@n"))]')
,	@x.exist('/r[@a=xs:anyURI   (sql:variable("@n"))]')
GO
Надо регать. Притом со ссылко что есть куча кода, которое нереально перелопатить а баг проявляется.
blackout, прошу зарегать на http://connect.microsoft.com/SQLServer/
Мы поддержим голосом.
Если нет акка, просто накатайте на буржуйском, я сам добавлю.

Более того, многое загадочно.
На странице: Сравнение типизированного и нетипизированного XML
Пишут:
MS
По этой причине типизированное XML-хранилище может занимать значительно меньше места, чем нетипизированное.

требуется оптимизировать хранение данных и обработку запросов на основе информации о типах;
Но при этом я так и не получил ни одного доказательства что это имеет место быть. Занимает столько же.
13 ноя 13, 17:42    [15123736]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить