Материал: Using_MySql,_MS_SQL_Server_and_Oracle

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

Проинициализируем данные в созданной таблице:

MySQL I Решение 3.1.2.b (очистка таблицы и инициализация данных) |

1-- Очистка таблицы:

2TRUNCATE TABLE 'subscriptions_ready';

3

4-- Инициализация данных:

5INSERT INTO 'subscriptions ready'

6

('sb id',

7

'sb subscriber'

8

'sb book',

9

'sb start',

10

'sb finish',

11

'sb is active')

12SELECT 'sb id',

13's name' AS 'sb subscriber'

14'b name' AS 'sb book',

15'sb start',

16'sb finish',

17'sb is active'

18 FROM 'books'

19JOIN 'subscriptions'

20ON 'b id' = 'sb book'

21JOIN 'subscribers'

22ON 'sb subscriber' = 's id';

Напишем триггеры, модифицирующие данные в кэширующей таблице. Источником данных являются таблицы books, subscribers и subscriptions, потому придётся создавать триггеры для всех трёх таблиц.

Поскольку MySQL версии 5.6 не позволяет создавать несколько однотипных триггеров на одной и той же таблице, перед выполнением следующего кода придётся удалить созданные в задаче 3.2.1 .a{215} триггеры с таблиц books и

subscriptions.

Регистрация в библиотеке новых книг и читателей никак не влияет на содержимое таблицы subscriptions, потому нет необходимости создавать INSERT- триггеры на таблицах books и subscribers — достаточно DELETE- и UPDATE -

триггеров.

Обратите внимание на несколько важных моментов в представленном ниже

коде:

внутри триггера в MySQL мы не можем явно или неявно подтверждать транзакцию, а потому не можем использовать для очистки таблицы оператор TRUNCATE (он является «нетранзакционным», и потому приводит к неявному подтверждению транзакции);

мы не храним в нашей кэширующей таблице идентификаторы книг, и потому не можем найти и удалить только отдельные записи (искать и удалять по названию книги тоже нельзя — несколько разных книг могут иметь одинаковое название), потому мы вынуждены каждый раз очищать всю таблицу и заново наполнять её данными;

в задаче 3.2.1.a{215} мы использовали BEFORE-триггеры, хотя могли использовать и AFTER — там это не имело значения, здесь же мы обязаны использовать только AFTER-триггеры, т.к. в противном случае в силу особенностей логики транзакций поведение MySQL отличается от ожидаемого, и информация в кэширующей таблице может не обновиться.

За исключением только что рассмотренных нюансов код тела обоих триггеров совершенно тривиален и представляет собой два запроса — на удаление всех

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 245/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

данных из таблицы и на наполнение таблицы данными на основе полученной выборки. Оба эти запроса можно выполнить совершенно отдельно от триггеров как самостоятельные SQL-конструкции.

В триггере, реагирующем на обновление информации о книге, есть проверка (строка 45) того, поменялось ли название книги. Если не поменялось, то нет необходимости обновлять закэшированные данные.

MySQL I

Решение 3.1.2.b (триггеры для таблицы books) |

1-- Удаление старых версий триггеров

2-- (удобно в процессе разработки и отладки):

3DROP TRIGGER 'upd sbs rdy on books del';

4DROP TRIGGER 'upd_sbs_rdy_on_books_upd';

5

6-- Переключение разделителя завершения запроса,

7-- т.к. сейчас запросом будет создание триггера,

8-- внутри которого есть свои, классические запросы:

9DELIMITER $$

10

11-- Создание триггера, реагирующего на удаление книг:

12CREATE TRIGGER 'upd sbs rdy on books del'

13AFTER DELETE

14ON 'books'

15FOR EACH ROW

16BEGIN

17DELETE FROM 'subscriptions_ready';

18INSERT INTO 'subscriptions ready'

19

 

('sb id',

20

 

'sb subscriber',

21

 

'sb book',

22

 

'sb start',

23

 

'sb finish'

24

 

'sb is active')

25

SELECT 'sb id',

26

 

's name',

27

 

'b name',

28

 

'sb start',

29

 

'sb finish'

30

 

'sb is active'

31

FROM

'books'

32

 

JOIN 'subscriptions'

33

 

ON 'b id' = 'sb book'

34

 

JOIN 'subscribers'

35

 

ON 'sb subscriber' = 's id';

36END;

37$$

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 246/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

MySQL I Решение 3.1.2.b (триггеры для таблицы books) (продолжение) |

38-- Создание триггера, реагирующего на

39-- изменение данных о книгах:

40CREATE TRIGGER 'upd_sbs_rdy_on_books_upd'

41AFTER UPDATE

42ON 'books'

43FOR EACH ROW

44BEGIN

45IF (OLD.'b name' != NEW.'b name')

46THEN

47DELETE FROM 'subscriptions_ready';

48INSERT INTO 'subscriptions ready'

49

 

('sb id'

50

 

'sb subscriber',

51

 

'sb book',

52

 

'sb start',

53

 

'sb finish',

54

 

'sb is active')

55

SELECT 'sb id',

56

 

's name',

57

 

'b name',

58

 

'sb start',

59

 

'sb finish',

60

 

'sb is active'

61

FROM

'books'

62

 

JOIN 'subscriptions'

63

 

ON 'b id' = 'sb book'

64

 

JOIN 'subscribers'

65

 

ON 'sb subscriber' = 's id';

66END IF;

67END;

68$$

69

70-- Восстановление разделителя завершения запросов:

71DELIMITER ;

Вся логика проверки работы таких триггеров подробно показана в решении{216} задачи 3.1.2.a{215}. Вы можете самостоятельно провести эксперимент, изменяя произвольным образом данные в таблице books и отслеживая соответствующие изменения в таблице subscriptions_ready.

Триггеры на таблице subscribers отличаются от триггеров на таблице books только своими именами, названиями своих таблиц и именем поля, изменение значения которого проверяется для определения необходимости обновления закэшированных данных (в коде выше проверяется поле b_name, в коде ниже — s_name).

MySQL і Решение 3.1.2.b (триггеры для таблицы subscribers) і

1-- Удаление старых версий триггеров

2-- (удобно в процессе разработки и отладки):

3DROP TRIGGER 'upd_sbs_rdy_on_subscribers_del';

4DROP TRIGGER 'upd_sbs_rdy_on_subscribers_upd';

6-- Переключение разделителя завершения запроса,

7-- т.к. сейчас запросом будет создание триггера,

8-- внутри которого есть свои, классические запросы:

9DELIMITER $$

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 247/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

MySQL I Решение 3.1.2.b (триггеры для таблицы subscribers) (продолжение) |

10-- Создание триггера, реагирующего на удаление книг:

11CREATE TRIGGER 'upd sbs rdy on subscribers del'

12AFTER DELETE

13ON 'subscribers'

14FOR EACH ROW

15BEGIN

16DELETE FROM 'subscriptions_ready';

17INSERT INTO 'subscriptions ready'

18

 

('sb id',

19

 

'sb subscriber',

20

 

'sb book',

21

 

'sb start'

22

 

'sb finish',

23

 

'sb is active')

24

SELECT 'sb id',

25

 

's name',

26

 

'b name',

27

 

'sb start'

28

 

'sb finish',

29

 

'sb is active'

30

FROM

'books'

31

 

JOIN 'subscriptions'

32

 

ON 'b id' = 'sb book'

33

 

JOIN 'subscribers'

34

 

ON 'sb subscriber' = 's id';

35END;

36$$

37

38-- Создание триггера, реагирующего на

39-- изменение данных о книгах:

40CREATE TRIGGER 'upd sbs rdy on subscribers upd'

41AFTER UPDATE

42ON 'subscribers'

43FOR EACH ROW

44BEGIN

45IF (OLD.'s name' != NEW.'s name')

46THEN

47DELETE FROM 'subscriptions_ready';

48INSERT INTO 'subscriptions ready'

49

 

('sb id',

50

 

'sb subscriber',

51

 

'sb book',

52

 

'sb start'

53

 

'sb finish',

54

 

'sb is active')

55

SELECT 'sb id',

56

 

's name',

57

 

'b name',

58

 

'sb start'

59

 

'sb finish',

60

 

'sb is active'

61

FROM

'books'

62

 

JOIN 'subscriptions'

63

 

ON 'b id' = 'sb book'

64

 

JOIN 'subscribers'

65

 

ON 'sb subscriber' = 's id';

66END IF;

67END;

68$$

69

70-- Восстановление разделителя завершения запросов:

71DELIMITER ;

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 248/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

На таблице subscriptions придётся создавать все три триггера (INSERT, UPDATE и DELETE), т.к. каждая из этих операций может повлиять на содержимое кэширующей таблицы subscriptions_ready. И код всех этих трёх триггеров будет сильно различаться.

MySQL I Решение 3.1.2.b (триггеры для таблицы subscriptions) |

1-- Удаление старых версий триггеров

2-- (удобно в процессе разработки и отладки):

3DROP TRIGGER 'upd sbs rdy on subscriptions ins';

4DROP TRIGGER 'upd sbs rdy on subscriptions del';

5DROP TRIGGER 'upd_sbs_rdy_on_subscriptions_upd';

7-- Переключение разделителя завершения запроса,

8-- т.к. сейчас запросом будет создание триггера,

9-- внутри которого есть свои, классические запросы:

10DELIMITER $$

11

12-- Создание триггера, реагирующего на добавление выдачи книг:

13CREATE TRIGGER 'upd_sbs_rdy_on_subscriptions_ins'

14AFTER INSERT

15ON 'subscriptions'

16FOR EACH ROW

17BEGIN

18INSERT INTO 'subscriptions ready'

19

 

('sb id',

20

 

'sb subscriber',

21

 

'sb book',

22

 

'sb start',

23

 

'sb finish',

24

 

'sb is active')

25

SELECT 'sb id',

26

 

's name',

27

 

'b name',

28

 

'sb start',

29

 

'sb finish',

30

 

'sb is active'

31

FROM

'books'

32

 

JOIN 'subscriptions'

33

 

ON 'b id' = 'sb book'

34

 

JOIN 'subscribers'

35

 

ON 'sb subscriber' = 's id'

36

WHERE 's id' = NEW.'sb subscriber'

37

AND 'b id' = NEW.'sb book';

38END;

39$$

40

41-- Создание триггера, реагирующего на удаление выдачи книг:

42CREATE TRIGGER 'upd_sbs_rdy_on_subscriptions_del'

43AFTER DELETE

44ON 'subscriptions'

45FOR EACH ROW

46BEGIN

47DELETE FROM 'subscriptions ready'

48WHERE 'subscriptions ready' 'sb id' = OLD.'sb id';

49END;

50$$

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 249/545

Источник: https://studfile.net/preview/16420333/