Здравствуйте, <Аноним>, Вы писали: А>В интербайсе прокатывает вот такой запрос, который удалит все записи кроме одной с повторяющимся id.
Нет, он удалит все дублирующиеся записи:
id value
-- -----
01 red
02 green
02 green
03 black
=>
id value
-- -----
01 red
03 black
а надо
id value
-- -----
01 red
02 green
03 black
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Особенности Interbase
От:
Аноним
Дата:
18.03.04 13:52
Оценка:
Здравствуйте, Sinclair, Вы писали:
На каком сервере ты это пробовал или так просто чисто интуитивно написал в Interbase удаляет все кроме одной это связано с тем, что Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться
Здравствуйте, <Аноним>, Вы писали: А>На каком сервере ты это пробовал или так просто чисто интуитивно написал в Interbase удаляет все кроме одной это связано с тем, что Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться
Охренеть! Специально поставил Interbase 6.5 для проверки. Я и раньше знал, что Interbase — редчайший отстой, но чтоб настолько жидко...
тест 1:
create table test(id int, val char(5));
insert into test values(1, 'red');
insert into test values(2, 'green');
insert into test values(3, 'blue');
insert into test values(2, 'green');*/
delete from test
where test.ID in (select id from test GROUP BY id HAVING count(id)>1);
select * from test;
Результат:
id value
-- -----
01 red
02 green
03 blue
Давайте убедимся, что это — страшный косяк. Попробуем вычислить предикат в условии Delete вручную и скормить уже его:
create table test(id int, val char(5));
insert into test values(1, 'red');
insert into test values(2, 'green');
insert into test values(3, 'blue');
insert into test values(2, 'green');*/
/* А вот так можно убедиться в том, что в in стоит именно эта коллекция:*/select id from test GROUP BY id HAVING count(id)>1;
delete from test
where test.ID in(2);
select * from test;
Результат:
id value
-- -----
01 red
03 blue
Здорово, да? То есть у нас результат запроса зависит от порядка вычисления аргументов. Мы вроде как сделали эквивалентную замену (а ведь SQL — это функциональный язык), а результат изменился. Другая особенность в том, что если бы у нас записи с ID = 2 различались в поле val, то результат запроса вообще получается неопределенным.
В общем, ребята, Interbase — не RDBMS. Нельзя ее применять. Самые простые и очевидные вещи сделаны там через ухо.
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
delete from Table1
where Table1.ID in (select id from Table1 GROUP BY id HAVING count(id)>1)
А>На каком сервере ты это пробовал или так просто чисто интуитивно написал в Interbase удаляет все кроме одной это связано с тем, что Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться
в принципе это логично... но это не работает.
я пробовал на ms sql
Здравствуйте, ilya_ny, Вы писали:
_>Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться _>в принципе это логично...
Это абсолютно не логично, и ни кто, кроме Интербейса, таких вольностей себе не позволяет.
Здравствуйте, Sinclair, Вы писали:
S>Здорово, да?
Не то слово...
А интересно, какой-нибудь INSERT INTO table ... SELECT ... FROM Table, в бесконечный цикл это чудо вгонит?
Или update не шибко не тривиальный?
Самое прикольное, что этот баг практически не пофиксишь, поскольку я более чем уверен, что умельцами уже написана куча кода в расчете на эту особенность, типа предложенного выше удаления дубликатов.
В итоге, если все исправить, то этот код перестанет работать правильно...
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, ilya_ny, Вы писали:
_>>Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться _>>в принципе это логично... M>Это абсолютно не логично, и ни кто, кроме Интербейса, таких вольностей себе не позволяет.
А можно меня тыкнуть в описание SQL92? Мне почему-то помнится, что в стандарте порядок вычисления не определен. А посему — на усмотрение разработчика. И MSSQL IB не указ
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Sinclair, Вы писали:
S>>Здорово, да? M>) Не то слово... M>А интересно, какой-нибудь INSERT INTO table ... SELECT ... FROM Table, в бесконечный цикл это чудо вгонит? M>Или update не шибко не тривиальный?
Скорее всего вгонит. Что написали — то и получите
M>Самое прикольное, что этот баг практически не пофиксишь, поскольку я более чем уверен, что умельцами уже написана куча кода в расчете на эту особенность, типа предложенного выше удаления дубликатов. M>В итоге, если все исправить, то этот код перестанет работать правильно...
В связи с чем исправлять? IB удовлетворяет стандарту SQL92. Где ошибка?
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, ilya_ny, Вы писали:
_>>Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться _>>в принципе это логично... M>Это абсолютно не логично, и ни кто, кроме Интербейса, таких вольностей себе не позволяет.
НАшел:
13.7 <delete statement: searched>
Function
Delete rows of a table.
Format
<delete statement: searched> ::=
DELETE FROM <table name>
[ WHERE <search condition> ]
[skipped]
General Rules
[skipped]
If <search condition> is specified, then it is applied to
each row of T with the <table name> bound to that row, and
all rows for which the result of the <search condition> is
true are marked for deletion.
The <search condition> is effectively evaluated for each row
of T before marking for deletion any row of T.
Each <subquery> in the <search condition> is effectively
executed for each row of T and the results used in the ap-
plication of the <search condition> to the given row of T.
If any executed <subquery> contains an outer reference to a
column of T, the reference is to the value of that column in
the given row of T.
3) If any row that is marked for deletion by the <delete statement:
searched> has been marked for deletion by any <delete statement:
positioned> that identifies some cursor CR that is still open
or updated by any <update statement: positioned> that identifies
some cursor CR that is still open, then a completion condition
is raised: warning-cursor operation conflict.
4) All rows that are marked for deletion are effectively deleted
at the end of the <delete statement: searched> prior to the
checking of any integrity constraint.
5) If no row is deleted, then a completion condition is raised: no
data.
Leveling Rules
1) The following restrictions apply for Intermediate SQL:
a) No leaf generally underlying table of T shall be an under-
lying table of any <query expression> generally contained in
the <search condition>.
Здравствуйте, Romkin, Вы писали:
R>Мне почему-то помнится, что в стандарте порядок вычисления не определен. А посему — на усмотрение разработчика.
Правильно, не определен. Поэтому конечный результат от порядка зависеть не должен, чувствуешь разницу?
А в IB зависит, и это не правильно.
И разработчик тут непричем, в таких вещах полагаться на разрработчика нельзя, это вотчина оптимизатора. А если результат зависит от порядка выполнения, то о сколь-либо эффективном оптимизаторе можно забыть, поскольку в этом случае у сервера практически не остается инструментов для оптимизации, он не может себе позволить сделать эквивалентное преобразование, поскольку в этом случае изменится результат запроса.
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Romkin, Вы писали:
R>>Мне почему-то помнится, что в стандарте порядок вычисления не определен. А посему — на усмотрение разработчика. M>Правильно, не определен. Поэтому конечный результат от порядка зависеть не должен, чувствуешь разницу? M>А в IB зависит, и это не правильно. M>И разработчик тут непричем, в таких вещах полагаться на разрработчика нельзя, это вотчина оптимизатора. А если результат зависит от порядка выполнения, то о сколь-либо эффективном оптимизаторе можно забыть, поскольку в этом случае у сервера практически не остается инструментов для оптимизации, он не может себе позволить сделать эквивалентное преобразование, поскольку в этом случае изменится результат запроса.
Я имел в виду разработчика этого самого оптимизатора.
Увы, в стандарте точно указано:
The <search condition> is effectively evaluated for each row
of T before marking for deletion any row of T.
All rows that are marked for deletion are effectively deleted
at the end of the <delete statement: searched> prior to the
checking of any integrity constraint.
Следовательно, IB пролетает Только что проверил на FB1.5 — тожесамо
Правда, у меня такого нет нигде, в таких случаях все идет через where current of
Здравствуйте, Romkin, Вы писали:
R>Скорее всего вгонит. Что написали — то и получите
Это нормально? Нет это не нормально...
Хотя, говорят, в FireBird'е это пофиксили...
R>IB удовлетворяет стандарту SQL92.
В каком месте?
Здравствуйте, Romkin, Вы писали:
R>Я имел в виду разработчика этого самого оптимизатора.
Ну ясен хобот, разработчик оптимизатора в таких условиях нервно курит и рвет остатки волос от отчаянья... Ну или идет писать нормальные оптимизаторы под другие сервера... =)
Понятно, почему оптимизатора в IB практически нет, он лишний раз чихнуть не может...
R>Увы, в стандарте точно указано:<...>
Тут дело даже не в операторе delete, а в том, что результат в принципе не должен зависить от порядка применения операторов.
R> Только что проверил на FB1.5 — тожесамое...
А вот это странно, вроде бы в FB это фиксили?
Мы уже победили, просто это еще не так заметно...
Re[12]: Особенности Interbase
От:
Аноним
Дата:
19.03.04 10:02
Оценка:
Здравствуйте, Merle, Вы писали:
R>> Только что проверил на FB1.5 — тожесамое... M>А вот это странно, вроде бы в FB это фиксили?
Hello, Merle!
M> Это нормально? Нет это не нормально...
Это не так как бы тебе хотелось, но докажи что это не нормально.
M> Хотя, говорят, в FireBird'е это пофиксили...
Мда? Не знал.
А что тут фиксить надо?
Здравствуйте, Arioch, Вы писали:
A>Это не так как бы тебе хотелось, но докажи что это не нормально.
Да при чем тут мое хотение? Это противоречит и стандарту и здравому смыслу. Подобное поведение приводит к зависимости результата от последовательности выполнения операторов, что, в свою очередь, приводит к невозможности написать более-менее толковый оптимизатор.
Это нормально?
M>> Хотя, говорят, в FireBird'е это пофиксили... A>Мда? Не знал.
Нет? Ну тогда это лишний повод не связываться с IB и его клонами...
A>А что тут фиксить надо?
Да не хотите не надо, что я — зверь какой?
Hello, Merle!
M> Это противоречит и стандарту
Цитата под руками есть?
M> и здравому смыслу.
Есть зоть один сервер, где бы ни-че-го не противоречило здравому смыслу?
M> Подобное поведение приводит к зависимости результата от M> последовательности выполнения операторов,
В данном случае, никаих вариантов последовательности нет.
Здравствуйте, Arioch, Вы писали:
A>Hello, Merle!
M>> Это нормально? Нет это не нормально... A>Это не так как бы тебе хотелось, но докажи что это не нормально.
Я уже выше привел выдержки из стандарта. Это действительно не нормально
Это противоречит и стандарту и здравому смыслу. Подобное поведение приводит к зависимости результата от последовательности выполнения операторов, что, в свою очередь, приводит к невозможности написать более-менее толковый оптимизатор.
Почему ты так решил? Оптимизатор нормально уже работает в FB. Кстати, я не думаю, что это противоречит здравому смыслу
M>>> Хотя, говорят, в FireBird'е это пофиксили... A>>Мда? Не знал. M>Нет? Ну тогда это лишний повод не связываться с IB и его клонами...