Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / merge + delete / 25 сообщений из 25, страница 1 из 1
28.05.2010, 13:52
    #36655422
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
create table TablePrimary (Id number, Val varchar( 255 ));

insert into TablePrimary (Id, Val) values ( 1 , 'p1');
insert into TablePrimary (Id, Val) values ( 2 , 'p2');
insert into TablePrimary (Id, Val) values ( 3 , 'p3');
insert into TablePrimary (Id, Val) values ( 4 , 'p4');
insert into TablePrimary (Id, Val) values ( 5 , 'p5');

create table TableSecondary (Id number, Val varchar( 255 ));

insert into TableSecondary (Id, Val) values ( 1 ,'s1');
insert into TableSecondary (Id, Val) values ( 3 ,'s3');
insert into TableSecondary (Id, Val) values ( 5 ,'s5');

merge into TableSecondary dest
  using TablePrimary src
    on (dest.Id = src.Id)
  when matched then
    update set dest.Val = src.Val
    where (src.Id= 3 )
  delete where (src.Id<> 3 );

select * from TableSecondary order by Id;
IdVal1s13p35s5
Почему не
IdVal3p3

Only those rows which match both the ON clause and the DELETE WHERE clause are deleted.

1 && 5 и под условие в on и под delete'вское where - попадают. Почему тогда не удалились? Или я не правильно что-то понял?
_________________
"Helo, word!" - 17 errors 56 warnings
...
Рейтинг: 0 / 0
28.05.2010, 14:04
    #36655457
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Опа, а
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
merge into TableSecondary dest
  using TablePrimary src
    on (dest.Id = src.Id)
  when matched then
    update set dest.Val = src.Val
    --where (src.Id=3)
  delete where (src.Id<> 3 );
как раз и дало ожидаемый
IdVal3p3
но ни грамма не поспособствовало пониманию...
Я предполагаю что должно происходить следующее:
1. Производиться join по on
2. По всем row полученного от join'a
2.1. Если выполняется where update'а - делается update
2.2. Если выполняется where delete'а - делается delete
Или я ошибаюсь?
...
Рейтинг: 0 / 0
28.05.2010, 14:06
    #36655463
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
...
Рейтинг: 0 / 0
28.05.2010, 14:37
    #36655553
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
env The only rows affected by this clause are those rows in the destination table that are updated by the merge operation.
Гм... Удаляются только те записи, которые про'update'лись? Но тогда зачем делать "лишний" update? Да и на пальцах:
1. Производиться join по on
2. По всем row полученного от join'a
2.1. Если выполняется where update'а - делается update
2.2. Если выполняется where update'а (т.е. запись про'update'лась) && where delete'а - делается delete
Но where update'а и where delete'а, как правило, взаимоисключающие:
http://www.oracle-wiki.ru/wiki/Merge
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
MERGE INTO destination_table dest
  USING (SELECT col1, col2, col3 FROM source_table) source1
      ON (dest.col1 = source1.col1)
      WHEN MATCHED THEN
          UPDATE SET dest.col2 = source1.col2,
                                   dest.col3 = source1.col3
          WHERE source1.col2 IS NOT NULL
          DELETE source1.col2 IS NULL
      WHEN NOT MATCHED THEN
           INSERT (dest.col1, dest.col2, dest.col3)
           VALUES (source1.col1, source1.col2, source1.col3)
           WHERE source1.col2 IS NOT NULL

Получается delete вообще не произойдет. Что и имеет место в первом примере .
IMHO, довольно-таки довольно неожиданное и нетривиальное поведение...
...
Рейтинг: 0 / 0
28.05.2010, 14:42
    #36655563
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_Soft,

авторУдаляются только те записи, которые про'update'лись? Но тогда зачем делать "лишний" update?

емнип, delete проходит по значениям получившимся после update. Т.е. одно из применений - помечаем записи как старые и сразу удаляем.
...
Рейтинг: 0 / 0
28.05.2010, 14:43
    #36655564
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_SoftНо where update'а и where delete'а, как правило, взаимоисключающие:
http://www.oracle-wiki.ru/wiki/Merge
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
MERGE INTO destination_table dest
  USING (SELECT col1, col2, col3 FROM source_table) source1
      ON (dest.col1 = source1.col1)
      WHEN MATCHED THEN
          UPDATE SET dest.col2 = source1.col2,
                                   dest.col3 = source1.col3
          WHERE source1.col2 IS NOT NULL
          DELETE source1.col2 IS NULL
      WHEN NOT MATCHED THEN
           INSERT (dest.col1, dest.col2, dest.col3)
           VALUES (source1.col1, source1.col2, source1.col3)
           WHERE source1.col2 IS NOT NULL

Получается delete вообще не произойдет. Опять ищем интерпретации, при том, что в документации ВСЕ поясняет один абзац. Вот вам следующе предложение:MERGEThe DELETE WHERE condition evaluates the updated value , not the original value that was evaluated by the UPDATE SET ... WHERE condition.
...
Рейтинг: 0 / 0
28.05.2010, 16:13
    #36655866
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
-2-MERGEThe DELETE WHERE condition evaluates the updated value , not the original value that was evaluated by the UPDATE SET ... WHERE condition.
И что Вы этим хотите сказать?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
merge into TableSecondary dest
  using TablePrimary src
    on (dest.Id = src.Id)
  when matched then
    update set dest.Val = src.Val
    where (src.Id= 3 )
  delete where (src.Id<> 3 );
здесь вообще в where delete'а src - TablePrimary, а модифицируется dest - TableSecondary
...
Рейтинг: 0 / 0
28.05.2010, 16:27
    #36655901
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_Soft,

Не понял вашего удивления.

Всё правильно, только строки попавшие под условия update прошли на вход delete.
...
Рейтинг: 0 / 0
28.05.2010, 16:30
    #36655913
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_Soft..Гм... Удаляются только те записи, которые про'update'лись? Но тогда зачем делать "лишний" update?..
IMHO, довольно-таки довольно неожиданное и нетривиальное поведение...
всё понятно и ожидаемо, если на сабж посмотреть в его развитии.
9i - в мерже дилитовой кляузы просто не было и, соответственно,
where в апдейтовой кляузе имел смысл ограничения всея when matched.
ну а когда дилит добавили, то добавили, как добавили.
можно считать что удаляются именно проапдейченные строки - мнемонически, наверное,
так понятнее осознать (и запомнить) сей камуфлет.
а взаправду ли апедейчутся ли они перед удалением, думаю, что нет.., ну а какая разница?
...
Рейтинг: 0 / 0
28.05.2010, 17:37
    #36656073
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
envНе понял вашего удивления.

Всё правильно, только строки попавшие под условия update прошли на вход delete.
http://www.oracle-wiki.ru/wiki/Merge
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
MERGE INTO destination_table dest
  USING (SELECT col1, col2, col3 FROM source_table) source1
      ON (dest.col1 = source1.col1)
      WHEN MATCHED THEN
          UPDATE SET dest.col2 = source1.col2,
                                   dest.col3 = source1.col3
          WHERE source1.col2 IS NOT NULL
          DELETE source1.col2 IS NULL
      WHEN NOT MATCHED THEN
           INSERT (dest.col1, dest.col2, dest.col3)
           VALUES (source1.col1, source1.col2, source1.col3)
           WHERE source1.col2 IS NOT NULL

На вход к update попадут записи у коих source1.col2 IS NOT NULL, далее они попадают на вход delete и проверяются на source1.col2 IS NULL. Ессесно такого не может быть, так как иначе они бы не попали под update. Два взаимоисключающих условия. delete, вопреки ожиданиям, - никогда не произойдет. Просто сам синтаксис, IMHO, не способствует интуитивно понятному трактованию сей конструкции.
orawishвсё понятно и ожидаемо, если на сабж посмотреть в его развитии.
9i
Да я тока-тока намедни с оракулом столкнулсо...
orawishа взаправду ли апедейчутся ли они перед удалением, думаю, что нет.., ну а какая разница ?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
create or replace trigger tr_AU_TableSecondary
after update
on TableSecondary
referencing new as new
for each row
  begin
    dbms_output.put_line('tr_AU_TableSecondary');
  end;
PL/SQL Developer -> DBMS Output
tr_AU_TableSecondary

Но в trigger'е ж может быть не невинное put_line, а кое-что посерьезнее...
...
Рейтинг: 0 / 0
28.05.2010, 17:47
    #36656093
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_Soft..
Но в trigger'е ж может быть не невинное put_line, а кое-что посерьезнее...
Что? ~армагедец? а по какому поводу?
в триггере или аудит живёт или реакция на изменение значений атрибутов .
пусть себе и аудитит и реагирует.
...
Рейтинг: 0 / 0
28.05.2010, 17:48
    #36656094
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_SoftНо в trigger'е ж может быть не невинное put_line, а кое-что посерьезнее...Может у оракла и не лучшая реализация MERGE, но что-то посерьезнее так или иначе требует навыков чтения документации: MERGEIf the update clause is executed, then all update triggers defined on the target table are activated.
...
Any delete triggers defined on the target table will be activated for each row deletion.
...
Рейтинг: 0 / 0
28.05.2010, 17:54
    #36656107
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_Soft,

Вы просто лучше не примеры на oracle-wiki.ru смотрите, а читайте доку от производителя. Там конечно тоже ляпы бывают, но реже.
...
Рейтинг: 0 / 0
28.05.2010, 18:15
    #36656138
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
orawishв триггере или аудит живёт или реакция на изменение значений атрибутов .
пусть себе и аудитит и реагирует.
А зачем реагировать на изменение атрибутов в row, которая затем будет удалена?
-2-Может у оракла и не лучшая реализация MERGE, но что-то посерьезнее так или иначе требует навыков чтения документации: MERGEIf the update clause is executed, then all update triggers defined on the target table are activated.
...
Any delete triggers defined on the target table will be activated for each row deletion.
Это Вы к чему? Что при update trigger сработает - дык мы это уже выяснили...
envВы просто лучше не примеры на oracle-wiki.ru смотрите, а читайте доку от производителя
Понято...
...
Рейтинг: 0 / 0
28.05.2010, 18:45
    #36656202
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Ex_Softorawishв триггере или аудит живёт или реакция на изменение значений атрибутов .
пусть себе и аудитит и реагирует.
А зачем реагировать на изменение атрибутов в row, которая затем будет удалена?
..
например, чтобы ~сошлось..
если на восходящую денормализацию посмотреть, то:
insert +5
update -2
delete -3
итого: 0
...
Рейтинг: 0 / 0
28.05.2010, 20:01
    #36656291
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
orawish[quot Ex_Soft
а взаправду ли апедейчутся ли они перед удалением, думаю, что нет.., ну а какая разница?

Triggers.

SY.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
29.10.2019, 10:33
    #39882593
escaper_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Всем доброго дня!

Предлагаю разминку: кто сможет предложить оптимальный способ решения этой задачи через MERGE?

Сам сделал так:

Код: plsql
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.
/*
3.	В LOCATIONS планируется сделать POSTAL_CODE обязательным полем. 
Если в ней есть такие офисы, у которых не указан POSTAL_CODE, но он используется в DEPARTMENTS, то поле заполнить как UNKNOWN, 
если не используется, то удалить
*/

MERGE INTO locations l USING (
                                SELECT
                                    ll.location_id   AS loc_id_1,
                                    dd.location_id   AS loc_id_2
                                FROM
                                    locations     ll
                                    LEFT JOIN departments   dd ON ( ll.location_id = dd.location_id )
                            )
x ON ( l.location_id = x.loc_id_1 )
WHEN MATCHED THEN UPDATE SET l.postal_code =
    CASE
        WHEN l.postal_code IS NULL THEN
            'UNKNOWN'
        ELSE
            l.postal_code
    END
DELETE
WHERE
    x.loc_id_2 IS NULL;
...
Рейтинг: 0 / 0
29.10.2019, 10:59
    #39882610
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
escaper_этой задачи http://www.bugtraq.ru/forum/faq/general/smart-questions.html] RTFM
...
Рейтинг: 0 / 0
29.10.2019, 16:14
    #39882788
merch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
escaper_, почти сделал.. но "поймал" ошибку ORA-00942.
...
Рейтинг: 0 / 0
07.11.2019, 08:58
    #39886047
escaper_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Elic,

Хотя простой ответ RTFM бывает оправдан, когда дается просто лентяю, ссылка на документацию (даже если это набор ключевых слов для поиска в Google) все же лучше.

Можете послать поближе? :)
...
Рейтинг: 0 / 0
07.11.2019, 09:05
    #39886050
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
escaper_
через MERGE
Ради зачем?
...
Рейтинг: 0 / 0
07.11.2019, 09:31
    #39886053
escaper_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
Через MERGE потому, что такое условие задачи. А как вы видите решение?
...
Рейтинг: 0 / 0
07.11.2019, 09:45
    #39886059
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
escaper_
Через MERGE потому, что такое условие задачи. А как вы видите решение?
update, delete, фиктивный merge для соблюдения "условие задачи".
...
Рейтинг: 0 / 0
07.11.2019, 10:12
    #39886075
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
escaper_,

delete, update или delete, modify not null default 'UNKNOWN'
...
Рейтинг: 0 / 0
07.11.2019, 11:35
    #39886131
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
merge + delete
escaper_
Сам сделал так:

Готовьтесь отражать ORA-30926
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / merge + delete / 25 сообщений из 25, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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