Выбрать главу

schema.sqclass="underline"

□ CREATE TABLE p r o d u c t_ c h a n g e s (

p r o d u c t _ id INTEGER

CONSTRAINT p ro d _ ch a n g e s_ p k PRIMARY KEY,

p r o d u c t _ t y p e _ id INTEGER

CONSTRAINT p ro d _ c h a n g e s _ f k _ p r o d u c t _ t y p e s

REFERENCE p r o d u c t _ t y p e s ( p r o d u c t _ t y p e _ id ) ,

name VARCHAR2(30) NOT NULL,

d e s c r i p t i o n VARCHAR2(50) ,

p r i c e NUMBER(5, 2)

);

Следующий запрос показывает столбцы p r o d u c t _ id , p r o d u c t _ t y p e _ id ,

name и p r i c e для строк таблицы p ro d u c t_ c h a n g e s :

□ SELECT product_id, product_type_id, name, price

FROM product_changes;

PRODUCT ID PRODUCT TYPE ID NAME PRICE

1 1 Modern S c ie n c e 40

2 1 New C h em i s t r y 35

3 S u p e rn o v a 2 5 .9 9 13

2 Lu n a r L a n d in g 1 5 .9 9 14

2 S u bma r ine 1 5 .9 9 15

2 A i r p l a n e s 1 5 .9 9

Допустим, вы хотите слить строки из таблицы p ro d u c t_ c h a n g e s в таблицу

p r o d u c t s следующим образом.

Изменение содержимого таблиц 271

■ Для существующих строк с совпадающими значениями p ro d u c t _ t y p e _

i d в таблицах p r o d u c t s и p r o d u c t_ c h a n g e s следует обновить строки

таблицы products значениями столбцов, перечисленными в таблице

p ro d u c t_ c h a n g e s . Например, у товара № 1 в таблице p ro d u c t_ c h a n g e s

указана другая цена, чем в таблице products, так что цену для товара

№ 1 в таблице p r o d u c t s следует обновить. Аналогично, у товара № 2

в таблице p ro d u c t_ c h a n g e s изменены название товара и его цена, так

что таблица products должна быть обновлена. Наконец, у товара № 3

изменилось значение столбца p r o d u c t _ t y p e _ id , так что таблица

products должна быть обновлена.

■ Для новых строк в таблице p r o d u c t_ c h a n g e s необходимо вставить эти

строки в таблицу p r o d u c t s . Товары № 13, №14 и № 15 являются новыми

по отношению к таблице products, поэтому должны быть вставлены

в таблицу products.

Следующий пример осуществляет слияние именно так, как оно было

определено выше, чтобы влить изменения из p ro d u c t_ c h a n g e s в p r o d u c t s :

□ MERGE INTO p r o d u c t s p

USING p ro d u c t_ c h a n g e s pc ON (

p . p r o d u c t _ id = p c . p r o d u c t _ id

)

WHEN MATCHED THEN

UPDATE

SET

p . p r o d u c t _ t y p e _ id = p c . p r o d u c t _ t y p e _ id ,

p.name = pc.name,

p . d e s c r i p t i o n = p c . d e s c r i p t i o n ,

p . p r i c e = p c . p r i c e

WHEN NOT MATCHED THEN

INSERT (

p . p r o d u c t _ id , p . p r o d u c t _ t y p e _ id , p.name,

p . d e s c r i p t i o n , p . p r i c e

) VALUES (

p c . p r o d u c t _ id , p c . p r o d u c t _ t y p e _ id , pc.name,

p c . d e s c r i p t i o n , p c . p r i c e

);

6 rows merged.

Примечание В папке SQL вы найдёте сценарий по имени merge_example.sql, который содержит

предыдущее выражение MERGE.

Следует отметить ряд связанных с оператором MERGE моментов.

■ Фраза MERGE INTO указывает название таблицы, в которую будут вливаться

строки. В примере таблицей, в которую будут вливаться строки,

является таблица products, имеющая псевдоним р, который используется

при ссылках в остальной части оператора MERGE.

272 Гпава 8

■ Фраза USING ... ON определяет соединение таблиц. В нашем примере

соединение производится по столбцу p r o d u c t _ id из таблиц products

и p r o d u c t_ c h a n g e s . Таблица p ro d u c t_ c h a n g e s имеет псевдоним рс, который

используется при ссылках в остальной части оператора

MERGE.

■ Фраза WHEN MATCHED THEN задаёт действия, предпринимаемые, когда

для строки оказывается выполненной фраза USING ... ON. В примере

подобным действием будет оператор UPDATE, устанавливающий значения

столбцов p r o d u c t _ t y p e _ id , name, d e s c r i p t i o n и p r i c e существующей

строки таблицы products равными значениям соответствующих

столбцов таблицы p ro d u c t_ c h a n g e s .

■ Фраза WHEN NOT MATCHED THEN задаёт действия, предпринимаемые, когда

фраза USING .. . ON для строки оказывается невыполненной. В примере

подобным действием будет оператор INSERT, который добавляет

строку в таблицу p r o d u c t s , используя значения столбцов из строки

таблицы p ro d u c t_ c h a n g e s .

Если выполнить предыдущий оператор MERGE, вы увидите информацию

о том, что обработано шесть строк. Это будут строки со значениями

p r o d u c t _ id 1, 2, 3, 13, 14 и 15. Следующий запрос извлекает эти шесть слитых

строк из таблицы p r o d u c t s :

П SELECT product_id, product_type_id, name, price

FROM products

WHERE product_id IN (1, 2, 3, 13, 14, 15);

ID PRODUCT_TYPE_ID NAME PRICE

1 1 Modern S c ie n c e 40

2 1 New C h em i s t r y 35

3 1 S upe rno va 2 5 .9 9

13 2 L u n a r L an d in g 1 5 .9 9

14 2 Subma r ine 15 .9 9

15 2 A i r p l a n e s 15 .9 9

Были выполнены следующие изменения:

■ У товара № 1 появилась новая цена.

■ У товара № 2 появились новое название и цена.

■ У товара № 3 изменился идентификатор типа товара.

■ Товары 13, 14 и 15 являются новыми.

Транзакции базы данных

Транзакцией базы данных называется группа операторов SQL, которая

выполняет логическую единицу работы. Можно представлять себе транзакцию

как неразделимый набор операторов SQL, который должен быть