Каков синтаксис для слияния-удаления целевых строк с фильтром? - PullRequest
0 голосов
/ 10 мая 2019

Я изучаю SQL в Oracle Dev Gym.Я беру класс Базы данных для разработчиков: Следующий уровень: Слияние, Крис Саксон.

Я не могу понять, как удалить строки с фильтром в целевой таблице.Даже приведенный пример не работает.Я посмотрел несколько других учебных пособий, и они тоже не работают.

Вот схема:

create table bricks_for_sale (
  colour   varchar2(10),
  shape    varchar2(10),
  price    number(10, 2),
  primary key ( colour, shape )
);

create table purchased_bricks (
  colour   varchar2(10),
  shape    varchar2(10),
  price    number(10, 2),
  primary key ( colour, shape )
);

insert into bricks_for_sale values ( 'red', 'cube', 4.95 );
insert into bricks_for_sale values ( 'blue', 'cube', 7.75 );
insert into bricks_for_sale values ( 'blue', 'pyramid', 9.99 );

commit;

Вот пример кода, который должен (1) вставитьновый ряд в bfs_for_sale bricks, (2) объединить bfs в pb купленные_блоки и (3) удалить существующие синие кирпичи из pb.Он скопирован и вставлен из учебника, поэтому он должен работать.

insert into bricks_for_sale values ( 'blue', 'cuboid', 5.99 );

select * from purchased_bricks;

merge into purchased_bricks pb
using bricks_for_sale bfs
on    ( pb.colour = bfs.colour and pb.shape = bfs.shape )
when not matched then
  insert ( pb.colour, pb.shape, pb.price )
  values ( bfs.colour, bfs.shape, bfs.price )
when matched then
  update set pb.price = bfs.price
  delete where pb.colour = 'blue' ;

select * from purchased_bricks;

rollback;

Результат -

|COLOUR|SHAPE  |PRICE|
|------|-------|-----|
|red   |cube   |4.95 |
|blue  |cuboid |5.99 |
|blue  |cube   |7.75 |
|blue  |pyramid|9.99 |

Это ожидаемое поведение?Я знал, что строка blue-cuboid-5.99 останется, потому что ее нет в исходной таблице.Однако разве не должны исчезнуть строки синего куба / пирамиды?Похоже, что предложение delete ничего не делает.

Я смотрел другие учебники по слиянию и удалению и до сих пор не могу понять, как использовать merge-delete или как он должен работать.

Ответы [ 2 ]

0 голосов
/ 11 мая 2019

Предложение delete немного странно, но позволяет просто выполнять дополнительные действия во время операции слияния.Он может входить в предложение вставки, предложение обновления или и то, и другое.Ключом к его использованию является осознание того, что работает только со строками, которые соответствуют условию ON .

В вашем случае purchased_bricks пусто в начале, поэтому ничто не соответствует ONпредложение и все проходит через предложение вставки.Следовательно, предложение delete не имеет никакого эффекта.

Это можно увидеть в действии, если вы не выполните откат и не выполните оператор слияния второй раз.

После выполнения слияния один раз:

select * from purchased_bricks;

COLOUR     SHAPE           PRICE
---------- ---------- ----------
blue       pyramid          9.99
blue       cube             7.75
red        cube             4.95
blue       cuboid           5.99

Теперь запустите его во второй раз, и вы получите:

merge into [...]

4 rows merged.

select * from purchased_bricks;

COLOUR     SHAPE           PRICE
---------- ---------- ----------
red        cube             4.95

Поскольку у нас в таблице bricks_for_sale были синий куб, пирамида и кубоид, все они совпалив предложении on все прошло через предложение merge, а синие были удалены.

Из документации :

Укажите DELETE where_clause для очисткиданные в таблице при ее заполнении или обновлении. Единственными строками, затронутыми этим предложением, являются те строки в целевой таблице, которые обновляются операцией слияния. Условие DELETE WHERE оценивает обновленное значение, а не исходное значение, которое было оценено с помощью UPDATE SET..Где состояние. Если строка таблицы назначения соответствует условию DELETE, но не включена в объединение, определенное предложением ON, то оно не удаляется. Любые триггеры удаления, определенные в целевой таблице, будут активированы для каждой строки.удаление.

0 голосов
/ 11 мая 2019

Когда к сопоставленному блоку не обращаются.купил_bricks в начале пусто, поэтому ничего не найдено.

Пример не имеет смысла.Зачем нам обновлять запись, а затем удалять ее в том же блоке?

...