
Бази даних-20210115T104840Z-001 / Реферат на тему _Современные СУБД_ / Using_MySql,_MS_SQL_Server_and_Oracle(1)
.pdf
Пример 22: обновление данных
2.3.2. Пример 22: обновление данных
Задача 2.3.2.a{190}: у выдачи с идентификатором 99 изменить дату возврата на текущую и отметить, что книга возвращена.
Задача 2.3.2.b{191}: изменить ожидаемую дату возврата для всех книг, которые читатель с идентификатором 2 взял в библиотеке 25-го января 2016-го года, на «плюс два месяца» (т.е. читатель будет читать их на два месяца дольше, чем планировал).
Ожидаемый результат 2.3.2.a: строка с первичным ключом, равным 99, примет примерно такой вид (у вас дата в поле sb_finish будет другой).
sb_id |
|
sb_subscriber |
|
sb_book |
sb_start |
sb_finish |
sb_is_active |
|||||
99 |
|
4 |
|
|
4 |
|
2015-10-08 |
2016-01-06 |
N |
|||
|
|
Ожидаемый результат 2.3.2.b: следующие строки примут такой вид. |
||||||||||
|
|
|
|
|
|
|
|
|||||
sb_id |
sb_subscriber |
|
sb_book |
sb_start |
sb_finish |
sb_is_active |
|
|||||
102 |
2 |
|
1 |
|
2016-01-25 |
2016-06-30 |
N |
|
|
|||
103 |
2 |
|
3 |
|
2016-01-25 |
2016-06-30 |
N |
|
|
|||
104 |
2 |
|
5 |
|
2016-01-25 |
2016-06-30 |
N |
|
|
Решение 2.3.2.a{190}:
Значение текущей даты можно получить на стороне приложения и передать в СУБД, тогда решение будет предельно простым (см. вариант 1), но текущую дату можно получить и на стороне СУБД (см. вариант 2), что не сильно усложняет запрос.
MySQL Решение 2.3.2.a
1-- Вариант 1: прямая подстановка текущей даты в запрос.
2UPDATE `subscriptions`
3 |
|
SET |
`sb_finish` = '2016-01-06', |
4 |
|
|
`sb_is_active` = 'N' |
5 |
|
WHERE |
`sb_id` = 99 |
6 |
|
|
|
7-- Вариант 2: получение текущей даты на стороне СУБД.
8UPDATE `subscriptions`
9 |
|
SET |
`sb_finish` = CURDATE(), |
10 |
|
|
`sb_is_active` = 'N' |
11 |
|
WHERE |
`sb_id` = 99 |
MS SQL Решение 2.3.2.a
1-- Вариант 1: прямая подстановка текущей даты в запрос.
2UPDATE [subscriptions]
3 |
|
SET |
[sb_finish] = CAST(N'2016-01-06' AS DATE), |
4 |
|
|
[sb_is_active] = N'N' |
5 |
|
WHERE |
[sb_id] = 99 |
6 |
|
|
|
7-- Вариант 2: получение текущей даты на стороне СУБД.
8UPDATE [subscriptions]
9 |
|
SET |
[sb_finish] = CONVERT(date, GETDATE()), |
10[sb_is_active] = N'N'
11WHERE [sb_id] = 99
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 190/545

Пример 22: обновление данных
Oracle Решение 2.3.2.a
1-- Вариант 1: прямая подстановка текущей даты в запрос.
2UPDATE "subscriptions"
3 |
|
SET |
"sb_finish" = TO_DATE('2016-01-06', 'YYYY-MM-DD'), |
4"sb_is_active" = 'N'
5WHERE "sb_id" = 99
6
7-- Вариант 2: получение текущей даты на стороне СУБД.
8UPDATE "subscriptions"
9 |
SET |
"sb_finish" = TRUNC(SYSDATE), |
10"sb_is_active" = 'N'
11WHERE "sb_id" = 99
Применение функции TRUNC в 9-й строке запроса нужно для получения из полного формата представления даты-времени только даты.
Внимательно следите за тем, чтобы ваши запросы на обновление данных содержали условие (в этой задаче — строки 5 и 11 всех трёх запросов). UPDATE без условия обновит все записи в таблице, т.е. вы «покалечите» данные.
Существует ещё две очень распространённых ошибки при решении любой задачи, связанной с понятием «текущая дата»:
1)Если пользователь и сервер с СУБД находятся в разных часовых поясах, каждые сутки возникает отрезок времени, когда «текущая дата» у пользователя и на сервере отличается. Это следует учитывать, внося соответствующие поправки либо на уровне отображения данных пользователю, либо на уровне хранения данных.
2)Если дата хранит в себе не только информацию о годе, месяце и дне, но и о часах, минутах, секундах (дробных долях секунд), операции сравнения могут дать неожиданный результат (например, что с 01.01.2011 по 01.01.2012 не прошёл год, если в базе данных первая дата представлена как «2011-01-01 11:23:17» и «сегодня» представлено как «2012-01-01 15:28:27» — до прохождения года остаётся чуть больше четырёх часов).
Универсального решения этих ситуаций не существует. Требуется комплексный подход, начиная с выбора оптимального формата хранения, заканчивая реализацией и глубоким тестированием алгоритмов обработки данных.
Решение 2.3.2.b{190}.
В отличие от предыдущей задачи, здесь крайне нерационален вариант с получением новой даты на стороне приложения и подстановкой готового значения в запрос (мы ведь не знаем, сколько записей нам придётся обработать, и у разных записей вполне могут быть разные исходные значения обновляемой даты). Таким образом, придётся добавлять два месяца к дате средствами СУБД.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 191/545

Пример 22: обновление данных
Типичная ошибка: разобрать дату на строковые фрагменты, получить числовое представление месяца, добавить к нему нужное «смещение», преобразовать назад в строку, и «собрать» новую дату. Представьте, что к 15-му декабря 2011-го года надо добавить шесть месяцев: 2011-12-15 2011-18-15. Получился 18-й месяц, что несколько нелогично. С отрицательными смещениями получается ещё более «забавная» картина.
Вывод: операции с добавлением или вычитанием временных интервалов нужно производить с помощью специальных средств, умеющих учитывать годы, месяцы, дни, часы, минуты, секунды и т.д.
|
MySQL |
|
Решение 2.3.2.b |
||||
|
1 |
|
UPDATE |
`subscriptions` |
|
||
|
2 |
|
SET |
|
`sb_finish` = DATE_ADD(`sb_finish`, INTERVAL 2 MONTH) |
|
|
|
3 |
|
WHERE |
`sb_subscriber` = 2 |
|
||
|
4 |
|
|
|
|
AND `sb_start` = '2016-01-25'; |
|
|
|
|
|||||
|
MS SQL |
|
Решение 2.3.2.b |
||||
|
1 |
|
UPDATE |
[subscriptions] |
|
||
|
2 |
|
SET |
|
[sb_finish] = DATEADD(month, 2, [sb_finish]) |
|
|
|
3 |
|
WHERE |
[sb_subscriber] = 2 |
|
||
|
4 |
|
|
|
|
AND [sb_start] = CONVERT(date, '2016-01-25'); |
|
|
|
|
|
|
|||
|
Oracle |
|
|
Решение 2.3.2.b |
|||
|
1 |
|
UPDATE |
"subscriptions" |
|
||
|
2 |
|
SET |
|
"sb_finish" = ADD_MONTHS("sb_finish", 2) |
|
|
|
|
|
|
|
|
|
|
3WHERE "sb_subscriber" = 2
4AND "sb_start" = TO_DATE('2016-01-25', 'YYYY-MM-DD');
Во всех трёх СУБД решения достаточно просты и реализуются идентичным образом, за исключением специфики функций приращения даты.
Для повышения надёжности операций обновления рекомендуется после их выполнения получать на уровне приложения информацию о том, какое количество рядов было затронуто операцией. Если полученное число не совпадает с ожидаемым, где-то произошла ошибка.
Да, мы не всегда можем заранее знать, сколько записей затронет обновление, но всё же существуют случаи, когда это известно (например, библиотекарь отметил чек-боксами некие три выдачи и нажал «Книги возвращены», значит, обновление должно затронуть три записи).
Задание 2.3.2.TSK.A: отметить все выдачи с идентификаторами ≤50 как возвращённые.
Задание 2.2.2.TSK.B: для всех выдач, произведённых до 1-го января 2012-го года, уменьшить значение дня выдачи на 3.
Задание 2.2.2.TSK.C: отметить как невозвращённые все выдачи, полученные читателем с идентификатором 2.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 192/545

Пример 23: удаление данных
2.3.3. Пример 23: удаление данных
Задача 2.3.3.a{193}: удалить информацию о том, что читатель с идентификатором 4 взял 15-го января 2016-го года в библиотеке книгу с идентификатором 3.
Задача 2.3.3.b{193}: удалить информацию обо всех посещениях библиотеки читателем с идентификатором 3 по воскресеньям.
Ожидаемый результат 2.3.3.a: следующая запись должна быть удалена.
sb_id |
sb_subscriber |
sb_book |
sb_start |
sb_finish |
sb_is_active |
101 |
4 |
3 |
2016-01-15 |
2016-01-30 |
N |
|
Ожидаемый результат 2.3.3.b: следующие записи должны быть удалены. |
||||
|
|
|
|
|
|
sb_id |
sb_subscriber |
sb_book |
sb_start |
sb_finish |
sb_is_active |
62 |
3 |
5 |
2014-08-03 |
2014-10-03 |
Y |
86 |
3 |
1 |
2014-08-03 |
2014-09-03 |
Y |
Решение 2.3.3.a{193}.
В данном случае решение тривиально и одинаково для всех трёх СУБД за исключением синтаксиса формирования значения поля sb_start.
MySQL Решение 2.3.3.a
1 DELETE FROM `subscriptions`
2 WHERE `sb_subscriber` = 4
3AND `sb_start` = '2016-01-15'
4AND `sb_book` = 3
MS SQL Решение 2.3.3.a
1 DELETE FROM [subscriptions]
2 WHERE [sb_subscriber] = 4
3AND [sb_start] = CONVERT(date, '2016-01-15')
4AND [sb_book] = 3
Oracle Решение 2.3.3.a
1DELETE FROM "subscriptions"
2WHERE "sb_subscriber" = 4
3AND "sb_start" = TO_DATE('2016-01-15', 'YYYY-MM-DD')
4AND "sb_book" = 3
Внимательно следите за тем, чтобы ваши запросы на удаление данных содержали условие (в этой задаче — строки 2-4 всех трёх запросов). DELETE без условия удалит все записи в таблице, т.е. вы потеряете все данные.
Решение 2.3.3.b{193}.
В решении{39} задачи 2.1.7.b{39} мы подробно рассматривали, почему в условиях, затрагивающих дату, выгоднее использовать диапазоны, а не извлекать фрагменты даты, и оговаривали, что могут быть исключения, при которых диапазонами обойтись не получится. Данная задача как раз и является таким исключением: нам
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 193/545

Пример 23: удаление данных
придётся получать информацию о номере дня недели на основе исходного значения даты.
MySQL Решение 2.3.3.b
1 DELETE FROM `subscriptions`
2 WHERE `sb_subscriber` = 3
3 AND DAYOFWEEK(`sb_start`) = 1
Обратите внимание: функция DAYOFWEEK в MySQL возвращает номер дня,
начиная с воскресенья (1) и заканчивая субботой (7).
MS SQL Решение 2.3.3.b
1 DELETE FROM [subscriptions]
2 WHERE [sb_subscriber] = 3
3AND DATEPART(weekday, [sb_start]) = 1
ВMS SQL Server функция DATEPART также нумерует дни недели, начиная с воскресенья.
Oracle Решение 2.3.3.b
1DELETE FROM "subscriptions"
2WHERE "sb_subscriber" = 3
3AND TO_CHAR("sb_start", 'D') = 1
Oracle ведёт себя аналогичным образом: получая номер дня недели, функция TO_CHAR начинает нумерацию с воскресенья.
Логика поведения функций, определяющих номер дня недели, может различаться в разных СУБД и зависеть от настроек СУБД, операционной системы и иных факторов. Не полагайтесь на то, что такие функции всегда и везде будут работать так, как вы привыкли.
Для повышения надёжности операций удаления рекомендуется после их выполнения получать на уровне приложения информацию о том, какое количество рядов было затронуто операцией. Если полученное число не совпадает с ожидаемым, где-то произошла ошибка.
Да, мы не всегда можем заранее знать, сколько записей затронет удаление, но всё же существуют случаи, когда это известно (например, библиотекарь отметил чек-боксами некие три выдачи и нажал «Удалить», значит, удаление должно затронуть три записи).
Задание 2.3.3.TSK.A: удалить информацию обо всех выдачах читателям книги с идентификатором 1.
Задание 2.2.3.TSK.B: удалить все книги, относящиеся к жанру «Классика».
Задание 2.2.3.TSK.C: удалить информацию обо всех выдачах книг, произведённых после 20-го числа любого месяца любого года.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 194/545

Пример 24: слияние данных
2.3.4. Пример 24: слияние данных
|
Задача 2.3.4.a{195}: добавить в базу данных жанры «Философия», «Детек- |
|||||
|
тив», «Классика». |
|||||
|
Задача 2.3.4.b{197}: скопировать (без повторений) в базу данных «Библио- |
|||||
|
тека» содержимое таблицы |
genres |
из базы данных «Большая библио- |
|||
|
тека»; в случае совпадения первичных ключей добавить к существую- |
|||||
|
щему имени жанра слово « [OLD]». |
|||||
|
|
|
||||
|
Ожидаемый результат 2.3.4.a: содержимое таблицы |
genres |
должно при- |
|||
|
нять следующий вид (обратите внимание: жанр «Классика» уже был в |
|||||
|
этой таблице, и он не должен дублироваться). |
|||||
|
|
|
||||
g_id |
g_name |
|
||||
1 |
Поэзия |
|
||||
2 |
Программирование |
|
||||
3 |
Психология |
|
|
|
|
|
4 |
Наука |
|
|
|
|
|
5 |
Классика |
|
|
|
|
|
6 |
Фантастика |
|
|
|
|
|
7 |
Философия |
|
|
|
|
|
8 |
Детектив |
|
|
|
|
|
|
Ожидаемый результат 2.3.4.b: этот результат получен на «эталонных |
|||||
|
данных»; если вы сначала решите задачу 2.3.4.a, в вашем ожидаемом |
|||||
|
результате будут находиться все восемь жанров из «Библиотеки» и 92 |
|||||
|
жанра со случайными именами из «Большой библиотеки». |
|||||
|
|
|
||||
g_id |
g_name |
1Поэзия [OLD]
2Программирование [OLD]
3Психология [OLD]
4Наука [OLD]
5Классика [OLD]
6Фантастика [OLD]
Иещё 94 строки со случайными именами жанров из «Большой библиотеки»
Решение 2.3.4.a{195}.
Во всех трёх СУБД на поле g_name таблицы genres построен уникальный индекс, чтобы исключить возможность появления одноимённых жанров.
Эту задачу можно решить, последовательно выполнив три INSERT-запроса, отслеживая их результаты (для вставки жанра «Классика» запрос завершится ошибкой). Но можно реализовать и более элегантное решение.
MySQL поддерживает оператор REPLACE, который работает аналогично INSERT, но учитывает значения первичного ключа и уникальных индексов, добавляя новую строку, если совпадений нет, и обновляя имеющуюся, если совпадение есть.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 195/545

Пример 24: слияние данных
MySQL |
Решение 2.3.4.a |
||
1 |
REPLACE INTO `genres` |
||
2 |
|
|
(`g_id`, |
3 |
|
|
`g_name`) |
4 |
VALUES |
(NULL, |
|
5 |
|
|
'Философия'), |
6 |
|
|
(NULL, |
7 |
|
|
'Детектив'), |
8 |
|
|
(NULL, |
9 |
|
|
'Классика') |
При таком подходе за один запрос (который выполняется без ошибок) мы можем передать много новых данных, не опасаясь проблем, связанных с дублированием первичных ключей и уникальных индексов.
К сожалению, MS SQL Server и Oracle не поддерживают оператор REPLACE,
но аналогичного поведения можно добиться с помощью оператора MERGE.
MS SQL Решение 2.3.4.a
1MERGE INTO [genres]
2USING ( VALUES (N'Философия'),
3 |
|
(N'Детектив'), |
4 |
|
(N'Классика') ) AS [new_genres]([g_name]) |
5ON [genres].[g_name] = [new_genres].[g_name]
6WHEN NOT MATCHED BY TARGET THEN
7INSERT ([g_name])
8VALUES ([new_genres].[g_name]);
Вэтом запросе строки 2-4 представляют собой нетривиальный способ динамического создания таблицы, т.к. оператор MERGE не может получать «на вход» ни-
чего, кроме таблиц и условия их слияния.
Строка 5 описывает проверяемое условие (совпадение имени нового жанра с именем уже существующего), а строки 6-8 предписывают выполнить вставку данных в целевую таблицу только в том случае, когда условие не выполнилось (т.е. дублирования нет).
Обратите внимание на то, что в конце строки 8 присутствует символ ;. MS SQL Server требует его наличия в конце оператора MERGE.
Oracle Решение 2.3.4.a
1MERGE INTO "genres"
2USING (SELECT ( N'Философия' ) AS "g_name"
3 |
FROM |
dual |
4UNION
5SELECT ( N'Детектив' ) AS "g_name"
6 |
FROM |
dual |
7UNION
8SELECT ( N'Классика' ) AS "g_name"
9 |
FROM |
dual) "new_genres" |
10ON ( "genres"."g_name" = "new_genres"."g_name" )
11WHEN NOT MATCHED THEN
12INSERT ("g_name")
13VALUES ("new_genres"."g_name")
Решение для Oracle построено по той же логике, что и решение для MS SQL Server. Отличие состоит только в способе динамического формирования таблицы (строки 2-9) из новых данных.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 196/545

Пример 24: слияние данных
Решение 2.3.4.b{195}.
Для решения этой задачи в MySQL вам нужно установить соединение с СУБД от имени пользователя, имеющего права на работу с обеими базами данных (предположим, что «Библиотека» у вас называется `library`, а «Большая библиотека»
— `huge_library`).
Далее остаётся воспользоваться вполне классическим INSERT ... SELECT (позволяет вставить в таблицу данные, полученные в результате выполнения запроса; строки 1-8), а условие задачи о добавлении слова « [OLD]» реализовать через специальный синтаксис ON DUPLICATE KEY UPDATE (строки 9-11), предписывающий MySQL выполнять обновление записи в целевой таблице, если возникает ситуация дублирования по первичному ключу или уникальному индексу между уже существующими и добавляемыми данными.
|
MySQL |
Решение 2.3.4.b |
||
|
1 |
|
INSERT INTO `library`.`genres` |
|
|
2 |
|
|
( |
|
3 |
|
|
`g_id`, |
|
4 |
|
|
`g_name` |
|
5 |
|
|
) |
6SELECT `g_id`,
7`g_name`
8 FROM `huge_library`.`genres`
9ON DUPLICATE KEY
10UPDATE `library`.`genres`.`g_name` =
11CONCAT(`library`.`genres`.`g_name`, ' [OLD]')
Для решения этой задачи в MS SQL Server (как и в случае с MySQL) вам нужно установить соединение с СУБД от имени пользователя, имеющего права на работу с обеими базами данных (предположим, что «Библиотека» у вас называется
[library], а «Большая библиотека» — [huge_library]).
MS SQL Server не поддерживает ON DUPLICATE KEY UPDATE, но аналогичного поведения можно добиться с использованием MERGE.
MS SQL Решение 2.3.4.b
1-- Разрешение вставки явно переданных значений в IDENTITY-поле:
2SET IDENTITY_INSERT [genres] ON;
3 |
|
|
|
4 |
|
-- Слияние данных: |
|
5 |
|
MERGE [library].[dbo].[genres] |
AS [destination] |
6USING [huge_library].[dbo].[genres] AS [source]
7ON [destination].[g_id] = [source].[g_id]
8WHEN MATCHED THEN
9UPDATE SET [destination].[g_name] =
10 |
|
CONCAT([destination].[g_name], N' [OLD]') |
11WHEN NOT MATCHED THEN
12INSERT ([g_id],
13[g_name])
14VALUES ([source].[g_id],
15[source].[g_name]);
16
17-- Запрет вставки явно переданных значений в IDENTITY-поле:
18SET IDENTITY_INSERT [genres] OFF;
Поскольку поле g_id является IDENTITY-полем, нужно явно разрешить вставку туда данных (строка 2) перед выполнением вставки, а затем запретить (строка 18).
Строки 5-7 запроса описывают таблицу-источник, таблицу-приёмник и проверяемое условие совпадения значений.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 197/545

Пример 24: слияние данных
Строки 8-10 и 11-15 описывают, соответственно, реакцию на совпадение (выполнить обновление) и несовпадение (выполнить вставку) первичных ключей таб- лицы-источника и таблицы-приёмника.
Для решения этой задачи в Oracle, (как и в случае с MySQL и MS SQL Server) вам нужно установить соединение с СУБД от имени пользователя, имеющего права на работу с обеими базами данных (предположим, что «Библиотека» у вас называ-
ется "library", а «Большая библиотека» — "huge_library").
Oracle как и MS SQL Server не поддерживает ON DUPLICATE KEY UPDATE,
но аналогичного поведения можно добиться с использованием MERGE.
Решение для Oracle аналогично решению для MS SQL Server, за исключением необходимости отключать (строка 2) перед вставкой данных триггер, отвечающий за автоинкремент первичного ключа, и снова включать его (строка 18) после вставки.
Oracle Решение 2.3.4.b
1-- Отключение триггера, обеспечивающего автоинкремент первичного ключа:
2ALTER TRIGGER "library"."TRG_genres_g_id" DISABLE;
3
4-- Слияние данных:
5MERGE INTO "library"."genres" "destination"
6USING "hude_library"."genres" "source"
7ON ("destination"."g_id" = "source"."g_id")
8WHEN MATCHED THEN
9UPDATE SET "destination"."g_name" =
10CONCAT("destination"."g_name", N' [OLD]')
11WHEN NOT MATCHED THEN
12INSERT ("g_id",
13"g_name")
14VALUES ("source"."g_id",
15"source"."g_name");
16
17-- Включение триггера, обеспечивающего автоинкремент первичного ключа:
18ALTER TRIGGER "library"."TRG_genres_g_id" ENABLE;
Если по неким причинам вы не можете соединиться с СУБД от имени пользователя, имеющего доступ к обеим интересующим вас схемам, можно пойти по следующему пути (такие варианты не были рассмотрены для MySQL и MS SQL Server, т.к. в этих СУБД нет поддержки некоторых возможностей, а сложность обходных решений выходит за рамки данной книги — на порядки проще создать пользователя с правами доступа к обеим базам данных (схемам)).
Строки 6-23 представленного ниже большого набора запросов аналогичны только что рассмотренному решению, а весь остальной код (строки 1-4, 25-37) нужен для того, чтобы обеспечить возможность одновременного доступа к данным в двух разных схемах.
Строки 2-4 отвечают за создание и открытие соединения к схеме-источнику.
Встроке 26 команда COMMIT нужна потому, что без неё при закрытии соединения мы рискуем потерять часть данных.
Встроках 29 и 32-34 представлены два варианта закрытия соединения. Как правило, срабатывает первые вариант, но если не сработал — есть второй.
Встроке 37 ранее созданное соединение уничтожается.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 198/545

Пример 24: слияние данных
Oracle Решение 2.3.4.b (работа от имени двух пользователей)
1-- Создание соединения со схемой-источником:
2CREATE DATABASE LINK "huge"
3CONNECT TO "логин" IDENTIFIED BY "пароль"
4USING 'localhost:1521/xe';
5
6-- Отключение триггера, обеспечивающего автоинкремент первичного ключа:
7ALTER TRIGGER "TRG_genres_g_id" DISABLE;
8
9-- Слияние данных:
10MERGE INTO "genres" "destination"
11USING "genres"@"huge" "source"
12ON ("destination"."g_id" = "source"."g_id")
13WHEN MATCHED THEN
14UPDATE SET "destination"."g_name" =
15 |
CONCAT("destination"."g_name", N' [OLD]') |
16WHEN NOT MATCHED THEN
17INSERT ("g_id",
18"g_name")
19VALUES ("source"."g_id",
20"source"."g_name");
21
22-- Включение триггера, обеспечивающего автоинкремент первичного ключа:
23ALTER TRIGGER "TRG_genres_g_id" ENABLE;
24
25-- Явное подтверждение сохранения всех изменений:
26COMMIT;
27
28-- Закрытие соединения со схемой источником:
29ALTER SESSION CLOSE DATABASE LINK "huge";
30
31-- Если не помогло ALTER SESSION CLOSE ... :
32BEGIN
33DBMS_SESSION.CLOSE_DATABASE_LINK('huge');
34END;
35
36-- Удаление соединения со схемой-источником:
37DROP DATABASE LINK "huge";
Задание 2.3.4.TSK.A: добавить в базу данных жанры «Политика», «Психология», «История».
Задание 2.3.4.TSK.B: скопировать (без повторений) в базу данных «Библиотека» содержимое таблицы subscribers из базы данных «Большая библиотека»; в случае совпадения первичных ключей добавить к существующему имени читателя слово « [OLD]».
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 199/545