Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
MSSQL7 sp3 Ниже представлены два ОДИНАКОВЫХ запроса, только вот результаты у них совершенно разные... Почему? И как этого избежать, так как запросы намного сложнее... это так сказать строгая "выжимка". 1 Запрос:-------------------------------------------- select * from ( select * from (select * from MyTable where from_x-to_x != 0 ) bb where (from_y - to_y)/(from_x-to_x) != 0 ) aa 1 Результат:----------------------------------------- Divide by zero error encountered. 2 Запрос:-------------------------------------------- select * from (select * from MyTable where from_x-to_x != 0 ) bb where (from_y - to_y)/(from_x-to_x) != 0 2 Результат:----------------------------------------- Набор из 623 записей... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2001, 07:21 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Черт ошибся когда копировал из клипборда: P.S. Надеюсь различия видны не вооруженным взглядом... Запрос 1 select * from ( select * from (select * from MyTable where from_x-to_x != 0 ) b1 where (from_y - to_y)/(from_x-to_x) != 0 ) a1 Запрос 2 select * from (select * from MyTable where from_x-to_x != 0 ) b1 where (from_y - to_y)/(from_x-to_x) != 0 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2001, 07:25 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
) нет не ошибся, это UltraBoard TAB'ы съел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2001, 07:27 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
А from_x, to_x, from_y, to_y - какого типа? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2001, 13:11 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Вадим, скорее всего ошибка случается на какой-то одной записи. Постарайся ее найти. Затем ксли можно пришли скрипт, который воспроизводит ошибку, т.е. create table... insert .. values ... select ... Да, и еще - какая у тебя версия сервера и SP - select @@version ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2001, 02:45 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
SQL7 SP3 - увидел. Хорошо. Посторайся сделать скрипт воспроизведения... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2001, 02:47 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
После долгих мучений сам нашел Дело было в том, что для MSSQL7 почему то, почему? Эти выражения не эквивалентны: where from_x <> to_x и where from_x - to_x != 0 В первом случае всё заработало без ошибочно... Но, я так и не понял механизм, происшедшего Придется просто принять на заметку и пользоваться. Мне кажется, всё дело в оптимизации запроса MSSQL'ем, соответсвенно как бы ее отключить? Может есть какой способ? Но, всё равно, мне не ясно - запросы одинаковые ПОЧЕМУ ответы разные??? TO_X NUMERIC(6,2) NOT NULL P.S. А конференции типа swrus-mssql-sql нет? Именно по хранимым процедурам и sql-ям... а не по администрированию? TO Алексей Ельцов: не сюда же это постить пиши мне на vav@newmail.ru перейдем в приват. А почему ты отвечал в 6:45 утра это у тебя работа так рано начинается? 8( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2001, 09:41 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Типичные проблемы при работе с числами с плавающей точкой. Кстати, в некоторых источниках эти числа справедливо называют приблизительными числами. Сравнение этих чисел на точное равенство (или неравенство) является стратегической ошибкой. Сравнение с 0 (которое имеет тип int) приводит к неявному преобразованию нуля к Float. При преобразовании могут возникнуть ошибки преобразования и ноль превратится не в ноль, а в очень маленькое число. Лучше сравнивать не на точное равенство, а на неравенство (например, where abs(X-Y)<1.0E-3. По первоначально поставленному вопросу могу сказать, что кроме тривиального деления на ноль при решении данной задачи могут возникать и другие ошибки. В частности, переполнение разрядной сетки (при делении очень большого числа на очень маленькое), потеря значимости (при делении очень маленького числа на очень большое). И еще. Реакция на подобные ошибки устанавливается опцией SET ARITH_ABORT ON/OFF (см BOL). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2001, 14:10 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
> TO Алексей Ельцов: не сюда же это постить Мне кажеся, что сюда - даже лучше. Я думаю, каждому кто следит за дискуссией будет интересно посмотреть на воспроизводимую ошибку. Тогда уже будет понятно в чем действительно дело. (Например, ты написал, что TO_X - numeric. А второй важный компонент - FROM_X - остался за кадром. Если-бы был скрипт воспроизведения, то было бы меньше вопросов и больше ответов) > А почему ты отвечал в 6:45 утра это у тебя работа так рано начинается? 8( У меня просто другой часовой пояс ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2001, 15:27 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
2 Vadim Я никогда не был в Южносахалинске, но достоверно знаю что и там используют MSSQL. А между тем когда москвичи после тяжелого трудового дня пьют пиво, на Сахалине уже начинается новый тяжелый трудовой день. Вот такая у нас большая страна. Имейте это ввиду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2001, 16:22 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Хмм. Алексей Вы правы, конечно насчет скрипта, но как бы проблема решилась. А подготовить скрипт это долго и потом я думаю все равно не выйдет ничего путного, а была не была ) Насчет FROM естественно он такой же как и TO, поэтому я про него и не написал CREATE TABLE MyTABLE ( NAME_REC NUMERIC(6,0) NOT NULL, TO_X NUMERIC(6,2) NOT NULL, FROM_X NUMERIC(6,2) NOT NULL, PRIMARY KEY (NAME_REC) ); А как сделать автоматический скрипт с данными, не перечислять же руками Insert Insert Insert ... Здесь еще кто-то слушает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2001, 09:57 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Конечно, с помощью insert'ов. Если результаты запросов различны, то достаточно наполнить таблицы-участники парой записей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2001, 16:40 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Напоминаю, что все это происходит в MSSQL7.0 sp2. В MSSQL6.5 ВСЁ РАБОТАЕТ! Ну что ж, каково же было мое удивление, когда я таки написал для вас этот скрипт! Я упростил до минимума и так и не понял, что это издевательство Микрософта? Если обратите внимание, тип данных я заменил на NUMERIC(6,0) и сделал всего 3 поля... 3-4 записи это необходимость, так как если убрать их, кажется, что все работает - просто выдается сообщение об ошибке... ан нет если добавить - видно, что в результат выводиться _только_ первая запись... P.S. Эх всю жизнь натыкаюсь на такого рода грабли, быть бы мне бетатестером у того же Микрософта... CREATE PROCEDURE tests AS CREATE TABLE #MyTABLE ( NAME_REC NUMERIC(6,0) NOT NULL, TO_X NUMERIC(6,0) NOT NULL, FROM_X NUMERIC(6,0) NOT NULL, PRIMARY KEY (NAME_REC) ); insert into #MyTable (name_rec,to_x,from_x) values (1, 78, 56) insert into #MyTable (name_rec,to_x,from_x) values (2, 79, 79) insert into #MyTable (name_rec,to_x,from_x) values (3, 58, 69) insert into #MyTable (name_rec,to_x,from_x) values (4, 57, 69) print '__________________________________________________________' print 'View all records:' print '__________________________________________________________' select * from #MyTable print '__________________________________________________________' print 'Result: All is good !' print '__________________________________________________________' select * from ( select * from #MyTable where from_x-to_x != 0 ) b1 where (from_x + to_x)/(from_x-to_x) != 0 print '__________________________________________________________' print 'Result: "Divide by zero"?!!' print '__________________________________________________________' select * from ( select * from ( select * from #MyTable where from_x-to_x != 0 ) b1 where (from_x + to_x)/(from_x-to_x) != 0 ) a1 print '__________________________________________________________' print 'Result: "Divide by zero"?!! Again !' print '__________________________________________________________' select * from ( select * from ( select * from #MyTable c1 where c1.from_x != c1.to_x ) b1 where (b1.from_x + b1.to_x)/(b1.from_x-b1.to_x) != 0 ) a1 print 'Copyright by Vadim Pristavko vav@newmail.ru 2001' drop table #MyTable return ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.09.2001, 11:07 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
IMHO оптимизатор пытается преобразовать Ваши выкрутасы к виду select * from #MyTable where ... and ... or ... etc., а, отнюдь, не к соединению подзапросов и, тем более, не к последовательному их выполнению. Отсюда и деление на ноль в условиях, что вполне закономерно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2001, 11:13 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Конечно, "оптимизатор" что-то там пытается сделать. А называть это выкрутасами?!! Мне, что же теперь работу с базой данных свести до одного select?! Да я уж лучше тогда в 6.5 вернусь, но это бред, такого быть не может. Запрос намного сложнее, как я говорил с самого начала. Здесь написан скрипт, который приводит к отказу _нормально_ постороенного запроса, причем прошу заметить, построенного по всем правилам ANSI может их уже кто отменил, чтобы нам удобнее было?! Вопрос остается ОТКРЫТЫМ! И ответа на него нет. Возможно, есть какая-то директива - отключения/включения этого оптимизатора, на время выполнения моего "выкрутасного" запроса? P.S. Неделю не мог достучаться до форума ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.10.2001, 06:51 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Очень классный пример Убираем в нем первый INSERT и получаем деление на 0 во всех трех селектах Так что вопрос скорее ставится с точностью наоборот - почему "нормальный" SELECT не выдает ошибку? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.10.2001, 21:20 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Ситуация следующая - в SQL 7.0 первый SELECT отрабатывает - остальные нет. в SQL 2000 первый SELECT тоже не отрабатывает. Мое объяснение приведенный селект оптимизируется в один SELECT, где WHERE (to_x-from_x>0 or to_x-from_x<0) and ((to_x+from_x)/(to_x+from_x)>0 or (to_x+from_x)/(to_x+from_x)>0) Если почитать документацию - там сказано - что ВСЕ условия OR и AND после WHERE обрабатываются сервером ОДНОВРЕМЕННО Как результат - в SQL 7.0 SELECT отработал из-за ПЛОХОЙ оптимизации Теперь о граблях - использование вложенных селектов может приводить к непредсказуемым результатам. Единственный выход - разбиение на несколько запросов с использованием временных таблиц (в 2000 таблицу можно декларировать в процедуре как переменную) В то же время - использование промежуточных таблиц приведет к существенному утяжелению запроса. и как следствие к снижению производительности и увеличению потребляемых ресурсов. Какие у народа будут мысли по этому поводу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.10.2001, 22:45 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Эээ, может просто добавит перед выполнением SET ARITHABORT OFF go SET ANSI_WARNINGS OFF go тогда по крайней мере выполнение запроса не будет прерываться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2001, 08:17 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Народ! А если подумать немного прежде чем делать запрос? Зачем нагружать сервер еще каким-то делением, если: а) проверка на неравность нулю делителя сделана; 6) частное будет =0 <-> делимое =0; То есть вместо (from_y - to_y)/(from_x-to_x) != 0 почему бы просто не оставить проверку (from_y - to_y)!=0 ? По-моему, этого будет достаточно, и накопленная погрешность будет значительно меньше. А? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2001, 08:32 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Да, что-то с Интернетом у нас стало... то на форум пробиться не мог, то у нас какие-то грабли Кстати, а нельзя подписаться на форум и получать его в виде News или E-Mail по типу subscribe.ru или yahoo groups? Касательно моего запроса, вставив в начало: SET ANSI_WARNINGS OFF SET ARITHIGNORE ON и в конец SET ANSI_WARNINGS ON SET ARITHIGNORE OFF (Она надо ли? По идее эта установка должна работать только на время и в теле моего запроса? Drop для таблицы точно не надо, но так мне спокойнее ) все заработало. Выход, пока, я вижу именно в создании временной таблицы/таблиц TO SerCh : я с самого начала сказал, что это _упрощенный_ вариант запроса, можно добавить значение to_x = -69 ... если бы все запросы были простые... вначале да, insert update select а потом select select select select select.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.10.2001, 08:48 |
|
||
|
Два одинаковых запроса - различный результат !!!
|
|||
|---|---|---|---|
|
#18+
Оптимизатор запросов преобразует твой запрос так, что деление на ноль оказывается в начале. Неприятно, конечно. Но с другой стороны, если посмотреть на выигрыш в скорости, который достигается для большого количества других запросов, то я согласен с таким неудобством. > Выход, пока, я вижу именно в создании временной таблицы/таблиц Я тоже сделал такой вывод. В 2000 возможно переменная типа таблица будет быстрее. Кстати, в 2000 все 3 из запроса из скрипта воспроизведения дают деление на ноль. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.10.2001, 16:54 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32014446&tid=1825328]: |
0ms |
get settings: |
6ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
31ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
80ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 364ms |

| 0 / 0 |
