powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / merge: не совпадают результаты FB и Oracle (again cursor stability ?)
25 сообщений из 31, страница 1 из 2
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587327
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all

LI-T3.0.0.30967

DDL:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
create table t(x int, y int);
create table t2(x int, y int);
commit;
insert into t values(5, 1);
insert into t values(4, 2);
insert into t values(3, 3);
insert into t values(2, 4);
insert into t values(1, 5);
commit;
insert into t2 select * from t;
commit;

DML-1 ("просто update"):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SQL> update t set y=(select count(*) from t where x<>y); select * from t; rollback;

           X            Y
============ ============
           5            4
           4            4
           3            4
           4            4
           1            4
-- OK --

DML-2 (merge, который должен привести вроде бы к тому же самому результату):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SQL> merge into t using(select x,y from t2) s on t.x=s.y when matched then update set t.y=(select count(*) from t where x<>y); select * from t; rollback;
-- NB: в условии соединения сравнение идёт с полем `y` из таблицы t 2 ; НЕТ поля ` t. y`, которое изменяется
-- (это не допускается в oracle, с которым далее сравниваю; поэтому и была введена таблица `t2`)
           X            Y
============ ============
           5            4
           4            2
           3            4
           4            2
           1            5

Сравниваю с Ora 11.2.g :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SH@ORA112G 23:10:40>merge into t using(select x,y from t2) s on (t.x=s.y) when matched then update set t.y=(select count(*) from t where x<>y);

SH@ORA112G 23:10:44>select * from t;

         X          Y
---------- ----------
         5          4
         4          4
         3          4
         2          4
         1          4

Any comments ?
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587334
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидAny comments ?
Оракул закэщировал результат подзапроса как инвариант, иначе результат был бы тем же.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587336
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

я попробовал без таблицы t2

Код: sql
1.
2.
3.
4.
5.
6.
7.
MERGE INTO T
USING RDB$DATABASE
ON 1=1
WHEN MATCHED THEN
    UPDATE SET Y = (SELECT COUNT(*)
                      FROM T
                      WHERE X <> Y);



Код: sql
1.
SELECT * FROM T;



Код: plaintext
1.
2.
3.
4.
5.
X	Y
5	4
4	4
3	3
2	3
1	3

Dimitry Sibiryakov,

инвариант инвариантом, но для запроса

Код: sql
1.
update t set y=(select count(*) from t where x<>y);



даёт результат правильный и не факт что там инвариант был закэширован
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587339
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисне факт что там инвариант был закэширован
План посмотри, там должно быть это видно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587345
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

не там не там не кэшируется

для MERGE

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Select Expression
    -> Singularity Check
        -> Aggregate
            -> Filter
                -> Table "T2" Full Scan
Select Expression
    ->  Nested Loop Join (inner)
        -> Filter
            -> Table "RDB$DATABASE" Full Scan
        -> Table "T1" Full Scan

для UPDATE

Код: plaintext
1.
2.
3.
4.
5.
6.
Select Expression
    -> Singularity Check
        -> Aggregate
            -> Filter
                -> Table "T" Full Scan
Select Expression
    -> Table "T" Full Scan

стабильность курсора Влад решал не через материализацию, а зачсёт раскрутки undo лога. Ну если это не так путь он меня поправит
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587346
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Код: sql
1.
2.
3.
4.
5.
6.
7.
MERGE INTO T T1
USING RDB$DATABASE
ON 1=1
WHEN MATCHED THEN
    UPDATE SET Y = (SELECT COUNT(*)
                      FROM T T2
                      WHERE T2.X <> T2.Y);



я приводил план для вот такого запроса (слегка изменённого).
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587359
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисдля запроса
Код: sql
1.
update t set y=(select count(*) from t where x<>y);

даёт результат правильныйв датском королевстве у "просто" апдейта, кажись, тоже трудности имеются.
Код: sql
1.
update t set y=(select count(*) from t ta join t tb on ta.x<>tb.y);

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Ora 11.2 & MS SQL 2005:
 X          Y
-- ----------
 5          5
 4          5
 3          5
 2          5
 1          5

FB LI-T3.0.0.30967:

 X            Y
== ============
 5            3
 4            3
 3            3
 4            3
 1            3
Код: sql
1.
update t set y=(select count(*) from t ta join t tb on ta.x<>tb.y);

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Ora 11.2 & MS SQL 2005:
 X          Y
-- ----------
 5         20
 4         20
 3         20
 2         20
 1         20

FB LI-T3.0.0.30967:

 X            Y
== ============
 5           22
 4           22
 3           22
 4           22
 1           22
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587360
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пардон, первый вариант апдейта такой:
Код: sql
1.
update t set y=(select count(*) from t ta join t tb on ta.x  = tb.y);

(РАВЕНСТВО вместо неравенства).

Занятно, что ФБ 2.5 выполняет его правильно :
Код: plaintext
1.
2.
3.
4.
5.
6.
 X            Y
== ============
 5            5
 4            5
 3            5
 2            5
 1            5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587363
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот попроще пример:

FB:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
SQL> select * from t; -- init data

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5

SQL> update t set y=(select count(*) from t ta where  ta.y=t.x ); select * from t; rollback;

           X            Y
============ ============
           5            1
           4            0
           3            1
           4            0
           1            1

SQL> update t set y=(select count(*) from t ta where  ta.y=t.y ); select * from t; rollback;

           X            Y
============ ============
           5            1
           4            2
           3            1
           4            2
           1            1

Oracle:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
SH@ORA112G 01:39:19>select * from t; -- init data

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
SH@ORA112G 01:39:24>update t set y=(select count(*) from t ta where  ta.y=t.x );
SH@ORA112G 01:39:26>select * from t;

         X          Y
---------- ----------
         5          1
         4          1
         3          1
         2          1
         1          1
SH@ORA112G 01:39:29>rollback;
SH@ORA112G 01:39:59>update t set y=(select count(*) from t ta where  ta.y=t.y );
SH@ORA112G 01:40:15>select * from t;

         X          Y
---------- ----------
         5          1
         4          1
         3          1
         2          1
         1          1
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587366
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Хьюстон, у нас проблемы".
В следующем DML поле ` y ` меняется на значение скалярного запроса select count(*), в котором это поле ВООБЩЕ НЕ УПОМИНАЕТСЯ.
Ну, и смотрим результат:

FB 3.0:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> select * from t; -- init data

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5

SQL> update t set  y =(select count(*) from t ta where  ta.x=t.x ); select * from t; rollback;

           X            Y
============ ============
           5            1
           4            2
           3            1
           4            2
           1            1


Oracle 11.2g:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SH@ORA112G 01:52:12>select * from t; -- init data

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
SH@ORA112G 01:52:15>update t set  y =(select count(*) from t ta where  ta.x=t.x );
SH@ORA112G 01:52:23>select * from t;

         X          Y
---------- ----------
         5          1
         4          1
         3          1
         2          1
         1          1

FB 2.5 выдаёт результат, как Oracle.
Чё-то в трёшке снова поломалось, КМК...
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587373
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И на десерт еще немного.
FB:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SQL> select * from t;

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5

SQL> insert into t select x,(select max(s) from (select count(x)over(partition by y)s from t)c ) from t; 

           X            Y
============ ============
           5            1
           4            2
           3            3
           4            2
           1            5
           5            2
           4            2
           3            2
           4            2
           1            2

Oracle:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SH@ORA112G 02:25:55>select * from t;

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
SH@ORA112G 02:25:59>insert into t select x,(select max(s) from (select count(x)over(partition by y)s from t)c ) from t;
SH@ORA112G 02:26:01>select * from t;

         X          Y
---------- ----------
         5          1
         4          2
         3          3
         2          4
         1          5
         5          1
         4          1
         3          1
         2          1
         1          1

Пойду вздремну слегонца. Всем приятных сновидений.

"I'llbe back!" (C) :-)
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587375
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЧё-то в трёшке снова поломалось, КМК...
Это не в трёшке поломалось, а у тебя в столбце Х две четвёрки, так что результат вполне
правильный. Поспать - правильное решение для этой проблемы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587394
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovПлан посмотри, там должно быть это видно.
не отображается это в плане
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587402
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovТаблоидЧё-то в трёшке снова поломалось, КМК...
Это не в трёшке поломалось, а у тебя в столбце Х две четвёрки, так что результат вполне
правильный. Поспать - правильное решение для этой проблемы.Да,перегрелся я вчера :(
2 IP / WS : потрите, плз, к ЧМ мои посты, начиная от 15731769 и до этого. Выглядят бестолковым шумом, всё там ОК с апдейтами.
:-[
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587429
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrне отображается это в плане
Мне почему-то показалось, что Денис запускал запрос на Оракуле...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587474
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Результат merge как-то связан с физической раскладкой записей
Вот скрипт, который пересоздаёт эти две таблицы с пятью строками, укладывая их каждый раз в random_порядке, и делающий этот самый merge.
"Результат превосходит ожидания": он такой же случайный, как и порядок записей в таблицах t & t2.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
commit;
recreate table t(x int, y int);
recreate table t2(x int, y int);
commit;

insert into t select r1, r2
from (select 6-row_number()over() r1, row_number()over() r2 from rdb$types rows 5)
order by rand();
commit;

--select * from t; 
insert into t2 select * from t order by rand();
commit;
--select * from t2;
merge into t using(select x,y from t2) s on t.x=s.y
when matched
  then update set t.y=(select count(*) from t where x<>y);
 
select * from t; 
rollback;
run
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
SQL> in rand_merge.sql;

           X            Y
============ ============
           1            4
           5            4
           3            4
           2            5
           4            5

SQL> in rand_merge.sql;

           X            Y
============ ============
           2            4
           1            4
           5            4
           3            4
           4            5

SQL> in rand_merge.sql;

           X            Y
============ ============
           5            4
           4            4
           2            3
           3            3
           1            3
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587483
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, оберни уже своё (select count(*) from t where x<>y) в детерминированную функцию...

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587488
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и чё, на каждый такой мёрдж свою детерм. ф-цию ваять ? ;-)

Странное дело: если мёрдж реализован как что-то типа этого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
for 
select s.id, t.f01, t.f02, (select count(*) from source sx join target tx on ...)
from target t
left join source s on t.id = s.id
into s_id, v_f01, v_f01, v_cnt
do begin
  if ( s_id is null ) then
     insert into source (f01, f02, fcnt) values( :v_f01, :v_f02, :v_cnt )
  else
    update source set f01 = :v_f01, f02 = :v_f02, fcnt = :v_cnt where id = s_id;
end

- то каким образом в нём вообще возникает вышепоказанная хрень ?
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587496
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

тут битва ведь не за результат конкретного запроса, а за правильность выполнения любого запроса как бы он не был записан и что бы там не думал оптимизатор
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587500
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоиди чё, на каждый такой мёрдж свою детерм. ф-цию ваять ? ;-)
Не на каждый. Достаточно на один, чтобы до тебя дошёл смысл первого ответа в этой теме.

Таблоидесли мёрдж реализован как что-то типа этого
С какого перепугу он так должен быть реализован? Он делается так:
Код: sql
1.
2.
3.
4.
for select rdb$db_key from t right join (select x,y from t2) s on t.x=s.y into :k
  if (k is null) // not matching branch
  else // matching branch
   update t set y=(select count(*) from t t3 where t3.x<>t3.y) where rdb$key=:k


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587504
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денистут битва ведь не за результат конкретного запроса
Угу, тут битва за право мучить хреново спроектированную базу дерьмозапросами и чтобы было
всё так как хочется левой пятке. В морг.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587506
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov битва за право мучить хреново спроектированную базу дерьмозапросами и чтобы было всё так как хочется левой пятке. В морг.Не, погодь! Тут битва за стабильность курсора как бэ... Вековая мечта почти сбылась, осталось поднажать еще чуток...
ЗЫ. И какие бы дерьмозапросы не сыпались в базу, если они синтаксически корректны, то результат их должен быть ПРАВИЛЬНЫМ.
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587514
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидНе, погодь! Тут битва за стабильность курсора как бэ...
Стабильность курсора это в пределах одного запроса. На подзапросы она не распространяется
ни в птице, ни в оракуле.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587519
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

да ну?
...
Рейтинг: 0 / 0
merge: не совпадают результаты FB и Oracle (again cursor stability ?)
    #38587526
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovСтабильность курсора это в пределах одного запроса . На подзапросы она не распространяется ни в птице, ни в оракуле.Может, всё же в пределах одного стейтмента , а не запроса ? http://tracker.firebirdsql.org/browse/CORE-3362
SQL Standard <...> requires that set of records which will be affected by UPDATE\DELETE statements should be evaluated first and real action (UPDATE or DELETE) should use this stable recordset. I.e. action implementation should not affect updating recordset in any way.
PS. В орацле ты не добьёшься случайных результатов вышепоказанного мёрджа, если будешь заталкивать в таблицу строки в random-порядке:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
SH@ORA112G 15:10:54>set feed off
SH@ORA112G 15:11:02>set timing off
SH@ORA112G 15:11:05>create table t(x int, y int);
SH@ORA112G 15:11:16>insert into t select r,6-r from (select level r from dual connect by level<=5)  order by dbms_random.value ;
SH@ORA112G 15:11:35>select * from t;

         X          Y
---------- ----------
         3          3
         2          4
         5          1
         4          2
         1          5
SH@ORA112G 15:11:39>commit;
SH@ORA112G 15:11:45>create table t2(x int, y int);
SH@ORA112G 15:11:55>insert into t2 select * from t;
SH@ORA112G 15:12:02>commit;
SH@ORA112G 15:12:47>merge into t using(select x,y from t2) s on (t.x=s.y) when matched then update set t.y=(select count(*) from t where x<
>y);
SH@ORA112G 15:13:05>select * from t;

         X          Y
---------- ----------
         3          4
         2          4
         5          4
         4          4
         1          4
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / merge: не совпадают результаты FB и Oracle (again cursor stability ?)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]