Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Раннее деление на ноль  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
select field1 / filed2
  from table
 where filed1 > 0
    and filed2 > 0

Подобный запрос выдаёт ошибку деления на 0
Но если я оператором case проверяю знаменатель, то всё ОК

Что за подстава такая?!

Причём на базе для разработки у меня этой ошибки не было и теперь головняк большой...
23 июл 09, 19:14    [7453396]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
поля field1 и field2, забейте на опечатку в этом форме нельзя редактировать свои сообщения
23 июл 09, 19:15    [7453399]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36808
План даст ответ на ваш вопрос.
23 июл 09, 19:17    [7453407]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
+-.
Guest
эээ... план бы глянуть... с продакшна...
23 июл 09, 19:17    [7453408]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
select @@version
и сервера разработки, и продакш сервера..

для спящего время бодрствования равносильно сну
23 июл 09, 19:18    [7453409]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
GlebZ
Member

Откуда: USA
Сообщений: 284
Поставьте
select field1 / NULLIF(field2,0)
  from table
 where field1  > 0
    and field2> 0

Водку? Водку - буду!
23 июл 09, 19:44    [7453491]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
это на каком диалекте?
Guest
GlebZ
Поставьте
select field1 / NULLIF(field2,0)
  from table
 where field1  > 0
    and field2> 0

Водку? Водку - буду!
23 июл 09, 19:46    [7453498]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
это на каком диалекте?
GlebZ
Поставьте
select field1 / NULLIF(field2,0)
  from table
 where field1  > 0
    and field2> 0

Водку? Водку - буду!
Это Вы про "водку" спрашиваете?
А если серьёзно, то в BOL глянуть - минутное дело.
23 июл 09, 20:03    [7453551]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
это снова я
Guest
iap
...
Это Вы про "водку" спрашиваете?
А если серьёзно, то в BOL глянуть - минутное дело.

Глянул. Незря.
мудрый BOL

NULLIF ( expression , expression )

Returns the same type as the first expression.

NULLIF returns the first expression if the two expressions are not equivalent. If the expressions are equivalent, NULLIF returns a null value of the type of the first expression.
23 июл 09, 20:24    [7453620]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
Версии совпадают, тем более я работал с бэкапом продакцена на девелоп-сервере...
Поверте мне запрос вы смотреть устаните, поэтому приведён пример.

Могу сказать что для моего частного случая была формулка

(f1/f1) / (d1/d2) что позволило мне нижний знаменатель поднять
(f1*d2/f1)/d1

Пример тоже упрощённый.
23 июл 09, 21:19    [7453678]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
ах, так вы еще и упростили
declare @t table (i1 int, i2 int)
insert into @t values(1,2)
insert into @t values(3,4)
insert into @t values(0,2)

select 1.0/i1/i2 from @t where i1>0 and i2>0
выдает 2 строки без ошибок.
чудес не бывает. ищите в коде ошибку.

для спящего время бодрствования равносильно сну
23 июл 09, 21:23    [7453682]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
как обойти nullif и case я прекрасно понимаю...
причём я лучше заранее знаменатель проверю...
Вопрос про то "откуда это взялось" и "как не менять везде".
23 июл 09, 21:28    [7453695]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
GlebZ
Member

Откуда: USA
Сообщений: 284
А зачем NULLIF обходить?
А вообще вы в коде смотрите, потому как у нас тут - работает.
Где-нибудь OR вкрался, например
Водку? Водку - буду!
23 июл 09, 22:16    [7453786]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
NIIIK
Вопрос про то "откуда это взялось" и "как не менять везде".
Ответ простой - сервер решил сначала посчитать возвращаемые выражения, а ограничение WHERE использовать потом.
А Вы думали, что он отбирает записи согласно WHERE перед вычислением, да?
Нет, как оптимизатор решит, так и будет. "Оптимальный" с его точки зрения алгоритм - тот, что быстрее.
Кстати, такая же ситуация с преобразованием строк в различные типы (числовые, даты и т.п.).
Тоже надо проверку прямо в списке SELECTа делать, а не уповать на WHERE.
24 июл 09, 08:44    [7454339]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
iap
NIIIK
Вопрос про то "откуда это взялось" и "как не менять везде".
Ответ простой - сервер решил сначала посчитать возвращаемые выражения, а ограничение WHERE использовать потом.
А Вы думали, что он отбирает записи согласно WHERE перед вычислением, да?
Нет, как оптимизатор решит, так и будет. "Оптимальный" с его точки зрения алгоритм - тот, что быстрее.
Кстати, такая же ситуация с преобразованием строк в различные типы (числовые, даты и т.п.).
Тоже надо проверку прямо в списке SELECTа делать, а не уповать на WHERE.


Я прекрасно понял что произошло, но меня это не устраивает... тем более что на одной базе работает, а на другой нет. Это естественно создаёт мне проблемы, когда я отдаю готовый скрипт, а мне говорят что "не работает"... и попробуй найди эту ошибку. Но всё равно большое спасибо за ответ.
Сейчас у меня на базе на девелоперском сервере всё ОК, а на продакшене уже другая выдаёт подобную ошибку. Потом понапоявляется куча ошибок из разряда "хрен поймаешь" и головняк будет... ведь у меня много кода подобного, потом перестанет что-то работать и мне скажут "отчёт не работает"... и попробуй догадайся что в процедуре отчёта есть использование функции, которая выдаёт ошибку, которую надо ещё впоймать.... а у себя я ей не поймаю и не будет её.

Алексей2003
ах, так вы еще и упростили
....
select 1.0/i1/i2 from @t where i1>0 and i2>0
выдает 2 строки без ошибок.
...


Ах да, мы упростили, что бы вам было понятнее jap точно понял суть вопроса и хотя бы сослался на то что "решает МС СКЛ"... хотя не согласно тому что написано. Я в списке полей мог бы написать просто константу, а условия должны были бы выполнится те же.
Я приатачил скрин нужной части, но обычно я стараюсь показывать саму суть, а не разводить флуд.
Я тут задаю не вопрсо а-ля "... как написать запрос..." сам их чёрт знает сколько написал и большую часть пока не на МсСКЛ (хотя последнее года только мс скл).
"чудеса бывают" это не законы физики или природы, это IT... я сам видел как true = true выдавало false в Делфе.... Так что в программировании много понятний типа bug, workaround и другие "это известная ошибка...". Это пользователю можно рассказывать что программа работает правильно и это какой-то постулат. А у нас "чудеса" могут скрваться как угодно глубок, на любом уровне.

К стает, nullif если попытаться применить, ошибочка никуда не уходит... а вот case вроде помог.

Мне что не нравится, то что сервер в следующий раз решит 1000 раз вызвать скалярную функцию, когда будет возвращатсья только 10 строк... и т. п.
Как подобным планом управлять?! хинты есть какие-нить?!

К сообщению приложен файл. Размер - 0Kb
24 июл 09, 15:00    [7457157]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Glory
Member

Откуда:
Сообщений: 104760
NIIIK
iap
NIIIK
Вопрос про то "откуда это взялось" и "как не менять везде".
Ответ простой - сервер решил сначала посчитать возвращаемые выражения, а ограничение WHERE использовать потом.
А Вы думали, что он отбирает записи согласно WHERE перед вычислением, да?
Нет, как оптимизатор решит, так и будет. "Оптимальный" с его точки зрения алгоритм - тот, что быстрее.
Кстати, такая же ситуация с преобразованием строк в различные типы (числовые, даты и т.п.).
Тоже надо проверку прямо в списке SELECTа делать, а не уповать на WHERE.


Я прекрасно понял что произошло, но меня это не устраивает... тем более что на одной базе работает, а на другой нет.

Просто надо запомнить, что порядок выполнения действий зависит не только от того, в какой последовательности вы их написали в тексте запроса.
24 июл 09, 15:04    [7457190]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
Glory, да у меня мозг переклинило от этого...
я ещё понимаю что в where условия написанные могут в любом порядке выполнится, там тем более нет никакого порядка (Как и порядка строк при выборке до order by), но то что сначала
where выполняется, а потом уже выбираются поля, срабатывают подзапросы в списке полей, выполняются функции и т. п. я по крайней мере всегда надеялся. Если подумать то я такими раскладами много много каких ошибок допустить, мало ли что у меня там в списке полей будет написано и будет вызываться.
24 июл 09, 15:20    [7457347]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Glory
Member

Откуда:
Сообщений: 104760
NIIIK
Glory, да у меня мозг переклинило от этого...
я ещё понимаю что в where условия написанные могут в любом порядке выполнится, там тем более нет никакого порядка (Как и порядка строк при выборке до order by), но то что сначала
where выполняется, а потом уже выбираются поля, срабатывают подзапросы в списке полей, выполняются функции и т. п. я по крайней мере всегда надеялся. Если подумать то я такими раскладами много много каких ошибок допустить, мало ли что у меня там в списке полей будет написано и будет вызываться.

Значит вы изначально неправильно думали.
Кроме того, поведение сервера при делении на 0 еще регулируется настройками ARITHABORT и ARITHIGNORE
24 июл 09, 15:27    [7457422]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36808
NIIIK
Glory, да у меня мозг переклинило от этого...
я ещё понимаю что в where условия написанные могут в любом порядке выполнится, там тем более нет никакого порядка (Как и порядка строк при выборке до order by), но то что сначала
where выполняется, а потом уже выбираются поля, срабатывают подзапросы в списке полей, выполняются функции и т. п. я по крайней мере всегда надеялся. Если подумать то я такими раскладами много много каких ошибок допустить, мало ли что у меня там в списке полей будет написано и будет вызываться.
Надо не надеяться, а смотреть на план выполнения зпроса.
24 июл 09, 15:28    [7457426]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
iljy
Member

Откуда:
Сообщений: 8711
NIIIK,
увы, мир не совершенен
кстати меня несколько озадачило утверждение, что не помог nullif(f2, 0). Вот:
select f1/nullif(f2,0)
from
(
	select 1. f1, 2. f2 union all
	select 1,3 union all
	select 2,0
) t
24 июл 09, 15:28    [7457428]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Гавриленко Сергей Алексеевич
NIIIK
Glory, да у меня мозг переклинило от этого...
я ещё понимаю что в where условия написанные могут в любом порядке выполнится, там тем более нет никакого порядка (Как и порядка строк при выборке до order by), но то что сначала
where выполняется, а потом уже выбираются поля, срабатывают подзапросы в списке полей, выполняются функции и т. п. я по крайней мере всегда надеялся. Если подумать то я такими раскладами много много каких ошибок допустить, мало ли что у меня там в списке полей будет написано и будет вызываться.
Надо не надеяться, а смотреть на план выполнения зпроса.
План может и поменяться со временем по разным причинам.
24 июл 09, 15:39    [7457533]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
iljy
NIIIK,
увы, мир не совершенен
кстати меня несколько озадачило утверждение, что не помог nullif(f2, 0). Вот:
select f1/nullif(f2,0)
from
(
	select 1. f1, 2. f2 union all
	select 1,3 union all
	select 2,0
) t


Самого озадачило, но в вашем примере он тоже не бужет нужен если написать

select f1/f2
from
(
	select 1. f1, 2. f2 union all
	select 1,3 union all
	select 2,0
) t
where f2 > 0

А у меня запрос такой (кроме того что охрененный), что он не долеж выбирать эти строки и без условия.
24 июл 09, 15:40    [7457559]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
qwrqwr
Member

Откуда: Msk
Сообщений: 1684
Glory
iap
NIIIK
Вопрос про то "откуда это взялось" и "как не менять везде".
Ответ простой - сервер решил сначала посчитать возвращаемые выражения, а ограничение WHERE использовать потом.
А Вы думали, что он отбирает записи согласно WHERE перед вычислением, да?
Нет, как оптимизатор решит, так и будет. "Оптимальный" с его точки зрения алгоритм - тот, что быстрее.
Кстати, такая же ситуация с преобразованием строк в различные типы (числовые, даты и т.п.).
Тоже надо проверку прямо в списке SELECTа делать, а не уповать на WHERE.
Просто надо запомнить, что порядок выполнения действий зависит не только от того, в какой последовательности вы их написали в тексте запроса.
Прошу прощения, я с соседнего форума - может это уже много раз обсуждалось - тогда киньте ссылкой.
Я до сегодняшнего дня считал, что where обрабатывается сервером строго до select - что соответствует стандарту SQL и подтверждено вроде документацией:
http://msdn.microsoft.com/ru-ru/library/ms189499.aspx
Порядок обработки инструкции SELECT
Следующие действия демонстрируют порядок обработки инструкции SELECT.

FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE или WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP

2 Glory, iap - не могли бы вы прокоментировать?
24 июл 09, 16:31    [7458045]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36808
iap
Надо не надеяться, а смотреть на план выполнения зпроса.
План может и поменяться со временем по разным причинам.
Это аргумент в пользу "не смотреть в план"? ;)

Сообщение было отредактировано: 24 июл 09, 16:32
24 июл 09, 16:31    [7458053]     Ответить | Цитировать Сообщить модератору
 Re: Раннее деление на ноль  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36808
qwrqwr
Я до сегодняшнего дня считал, что where обрабатывается сервером строго до select - что соответствует стандарту SQL и подтверждено вроде документацией:
http://msdn.microsoft.com/ru-ru/library/ms189499.aspx
Порядок обработки инструкции SELECT
Следующие действия демонстрируют порядок обработки инструкции SELECT.

FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE или WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP

2 Glory, iap - не могли бы вы прокоментировать?
Вообще-то select и вычисление каких-то выражений - не обязательно одно и то же. Но можете придраться к формулирвке. Только я сомневаюсь, что это признают багом.

Сообщение было отредактировано: 24 июл 09, 16:35
24 июл 09, 16:34    [7458080]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить