2015-06-10 3 views
1

Для следующего вопроса сказано, что ответ должен быть C. Но я думаю, что правильным ответом является «Ответ D», поскольку блок NOT MATCHED вставляет все unmatching записи в целевую таблицу. Может ли кто-нибудь объяснить это? Спасибо.Слияние таблицы в Oracle с условием удаления, ссылающимся на исходную таблицу

Q) Просмотрите экспозицию и просмотрите данные в таблицах ORDERS_MASTER и MONTHLY_ORDERS.

enter image description here

Оценить следующий MERGE заявление:

MERGE INTO orders_master o 
USING monthly_orders m 
ON (o.order_id = m.order_id) 
WHEN MATCHED THEN 
UPDATE SET o.order_total = m.order_total 
DELETE WHERE (m.order_total IS NULL) 
WHEN NOT MATCHED THEN 
INSERT VALUES (m.order_id, m.order_total); 

Что бы результат выше заявление?

А. В таблице ORDERS_MASTER будет содержать ORDER_IDs 1 и 2.

В. ORDERS_MASTER таблица будет содержать ORDER_IDs 1,2 и 3.

С. В таблице ORDERS_MASTER будет содержать ORDER_IDs 1 , 2 и 4.

Д. ORDERS_MASTER таблица будет содержать идентификаторы заказов 1,2,3 и 4.

Ответ: С

ответ

1

Правильный ответ - это действительно C, это связано с тем, что источником операции слияния является таблица monthly_orders, которая содержит только две записи с order_id 2 и 3 соответственно.

Подумайте о том, что будет происходить для каждого из этих записей:

  • Для order_id = 2, поскольку этот идентификатор существует в order_master таблицы, мы будем выполнять MATCHED части заявления слияния, обновляя order_total 2500 Поскольку количество для этой записи не NULL, DELETE ничего не сделает.
  • Для order_id = 3, опять-таки, идентификатор существует в order_master таблице, поэтому мы выполняем MATCHED часть заявления слияния, обновляя order_total к NULL, а затем оформив DELETE на order_master для строки мы просто обновляется, так как количество на monthly_orderNULL.

Это оставляет нас с order_id 1, 2 и 4, что соответствует ответ C.

Code

CREATE TABLE orders_master (
    order_id NUMBER(1) NOT NULL 
    ,order_total NUMBER(10) NULL 
) 
/

CREATE TABLE monthly_orders (
    order_id NUMBER(1) NOT NULL 
    ,order_total NUMBER(10) NULL 
) 
/

INSERT INTO orders_master (order_id, order_total) VALUES (1, 1000) 
/

INSERT INTO orders_master (order_id, order_total) VALUES (2, 2000) 
/

INSERT INTO orders_master (order_id, order_total) VALUES (3, 3000) 
/

INSERT INTO orders_master (order_id, order_total) VALUES (4, NULL) 
/

INSERT INTO monthly_orders (order_id, order_total) VALUES (2, 2500) 
/

INSERT INTO monthly_orders (order_id, order_total) VALUES (3, NULL) 
/

MERGE INTO orders_master o 
USING monthly_orders m 
ON (o.order_id = m.order_id) 
WHEN MATCHED THEN 
    UPDATE SET o.order_total = m.order_total 
    DELETE WHERE m.order_total IS NULL 
WHEN NOT MATCHED THEN 
    INSERT VALUES (m.order_id, m.order_total) 
/

COMMIT 
/


SQL> select * from orders_master 
2/

    ORDER_ID ORDER_TOTAL 
---------- ----------- 
     1  1000 
     2  2500 
     4 
+0

Благодаря ninesided. Мне показалось, что «WHEN NOT MATCHED» оценивается после «DELETE», а затем Order_ID 3 снова добавляется в целевую таблицу, делая все 1,2,3 и 4 доступными в целевой таблице. – CAD

+0

Если вы не возражаете, можете ли вы изучить этот вопрос. http://stackoverflow.com/questions/30755192/version-query-output-after-insert-update-and-delete – CAD