Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Jaffar Member Откуда: Сообщений: 633 |
выражение cast((RAND() * count(*) over()) as int) - иногда может принимать значение = 0 - это нормально НО функция NULLIF(0, 0) - должна возвращать NULL, и возвращать 0 с такими аргументами в принципе не должна, однако следующий запрос говорит об обратном declare @I int, @J int set @I = -1 set @J = 0 while( @I != 0) begin select @I = IsNULL(NULLIF(cast((RAND() * count(*) over()) as int), 0), 1) from sys.objects t set @J = @J + 1 end select @I '@I === 0', @J '@J' Посмотрел вот тут http://msdn.microsoft.com/ru-ru/library/ms177562.aspx: "В функции NULLIF не рекомендуется использовать такие зависимые от времени функции, как RAND(). Это может приводить к тому, что функция будет вычисляться дважды с возвратом различных результатов для каждого из вызовов. " - ну это понятно т.к. RAND() зависит от времени. Чем объяснить такое свинское поведение? |
22 ноя 13, 07:20 [15171871] Ответить | Цитировать Сообщить модератору |
Jaffar Member Откуда: Сообщений: 633 |
Версия: Microsoft SQL Server 2012 - 11.0.2100.60 (X64) Feb 10 2012 19:39:15 Copyright (c) Microsoft Corporation Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) |
22 ноя 13, 07:22 [15171873] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31779 |
Не понимаю, зачем вычислять дважды аргумент и почему это за десятилетия не сделано нормально... |
||
22 ноя 13, 07:33 [15171888] Ответить | Цитировать Сообщить модератору |
Jaffar Member Откуда: Сообщений: 633 |
т.е. функция NULLIF в С++ нотации имеет примерно такой вид:void NULLIF(expr1, expr2) { if(value(expr1) = value(expr2)) return(NULL) else return(value(expr1)) } и соотв. для RAND() ,будет иметь такой вид: void NULLIF(expr1, expr2) { if(value(RAND()) = value(expr2)) return(NULL) else return(value(RAND())) } --- т.е. все функции из expr1 - вызываются 2 раза --- тоже самое наверное будет справедливо и для newID() и для getdate() ---- на мой взгляд д.б. как-то так: void NULLIF(expr1, expr2) { declare @val1 void, @val2 void set @val1 = value(expr1) set @val2 = value(expr2) if(@val1 = @val2) return(NULL) else return(@val1) } |
22 ноя 13, 08:35 [15171995] Ответить | Цитировать Сообщить модератору |
Jaffar Member Откуда: Сообщений: 633 |
т.е. тоже самое справедливо и для функции IsNULL и т.п.? ведь она тоже хотябы разок да должна вычислить значение expr1 чтобы победить такое поведение - нужно использовать RAND() так select * from TABLE_1 cross apply(select RAND() RANDX) t2 |
22 ноя 13, 08:56 [15172056] Ответить | Цитировать Сообщить модератору |
daw Member Откуда: Муром -> Москва Сообщений: 7381 |
Jaffar, для isnull, вроде бы, не наблюдалось такого. а nullif - она в плане через case раскрывается, причем, это Searched CASE. да, примерно так, как вы расписали: [Expr1041] = Scalar Operator(isnull(CASE WHEN CONVERT(int,rand()*CONVERT_IMPLICIT(float(53),[Expr1039],0),0)=(0) THEN NULL ELSE CONVERT(int,rand()*CONVERT_IMPLICIT(float(53),[Expr1040],0),0) END,(1))) кстати, simple case
тоже раскрывается через searched. была, помнится, темка: https://www.sql.ru/forum/548590/pravilo-bag-ili-ficha |
||
22 ноя 13, 09:50 [15172284] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Да, для isnull такого нет. Потому что в MSSQL есть внутренняя функция isnull, которая показывается в планах запросов. А для coalesce — наблюдается, т.к. он тоже раскрывается в case, как и nullif. То есть nullif, coalesce — суть синтаксический сахар. В отличие от isnull. |
||
22 ноя 13, 12:19 [15173167] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31779 |
|
||
22 ноя 13, 12:33 [15173290] Ответить | Цитировать Сообщить модератору |
Mnior Member Откуда: Кишинёв Сообщений: 6723 |
Errors in the topic of coalesce() COALESCE((subquery), 1) may return NULL NULLIF works incorrectly with non-deterministic functions such as RAND() Голосуем независимо от состояния. Ставим комментарии. |
||
22 ноя 13, 18:29 [15176325] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |