
- •Введение.
- •Соединение с бд Oracle.
- •Типы данных Oracle, создание и модификация таблиц и вьюшек.
- •Задача. Удаление дубликатов.
- •Задача. Удаление по условию not in.
- •Функции по работе со строками.
- •Функции по работе с числами.
- •Троичная логика, конструкция with, функции nvl, coalesce, case, decode.
- •Основы pl/sql.
- •Задача. Факториал.
- •Задача. Подсчет числа вхождений символа в строку.
- •Задача. Подсчет числа вхождений подстроки в строку.
- •Задача. Копирование таблицы фиксированной структуры.
- •Задача. Простановка count в цикле.
- •Задача. Распределение данных по условию.
- •Задача. Использование сиквенсов и dbms_random.
- •Задача. Процедура с out параметрами. Нотации.
- •Задача. Простой пакет.
- •Задача. Разные виды Count.
- •Задача. Получение скрипта заполнения таблицы имеющимися данными.
- •Раздача прав (grants).
- •Операции над множествами, joins.
- •Задача. Сравнение множеств.
- •Задача. Загрузка данных с помощью full join.
- •Задача. Проставление роста животных.
- •Оператор merge.
- •Задача. Merge данных о студентах.
- •Задача. Merge данных о клиентах.
- •Функции по работе с датами.
- •Словарь данных.
- •Задача. Last_ddl_time.
- •Задача. Отчет об объектах текущей схемы.
- •Задача. Dbms_output из явного курсора по словарю данных.
- •Задача. Компиляция схемы.
- •Задача. Поиск текста во вьюшках.
- •Динамический sql.
- •Задача. Удаление конкретной таблицы, если она существует.
- •Задача. Удаление любой таблицы с проверкой на существование.
- •Задача. Конструкция '%rowcount'.
- •1) С помощью динамического вызова команды truncate очистить таблицу kk_objects_list от данных.
- •3) Вставить в таблицу kk_objects_list перечень имен всех объектов текущей схемы. С помощью конструкции sql%rowcount выдать в dbms_output количество вставившихся строк.
- •Задача. Удаление всех таблиц и вьюшек.
- •Часть 1. Написать pl/sql блок, который дропает все таблицы текущей схемы, начинающиеся на 'kk_'.
- •Часть 2. Написать pl/sql блок, который выдает в dbms_output скрипт удаления всех вьюшек текущей схемы, начинающихся с 'vw_kk%'.
- •Задача. Отчет о максимальных id.
- •Задача. Переименование столбцов.
- •Задача. Создание вьюшек.
- •Триггеры.
- •Задача. Автоинкрементное поле.
- •Задача. Триггер конвертации сумм в валюте.
- •Задача. Триггер логирования dml-операций.
- •Задача. Триггер зеркалирования.
- •Задача. Триггер по поиску в справочнике.
- •Задача. Триггер контроля.
- •Global temporary tables и переменные в заголовке пакета.
- •Переменные в заголовке пакета.
- •Регулярные выражения.
- •Задача. Правка некачественных данных регулярными выражениями.
- •Задача. Парсинг строк с помощью регулярных выражений.
- •Автономные транзакции.
- •Задача. Автономное логирование этапов загрузки.
- •Иерархические запросы.
- •Задача. Вывод иерархии с отступами.
- •Задача. Соединение иерархической таблицы с обычной.
- •Задача. Сумма зарплат подчиненных.
- •Задача. Простой календарь.
- •Задача. Детальный календарь.
- •Задача. Календарь с индикаторами выходных дней.
- •Аналитические функции.
- •Отступление о Rownum.
- •Негрупповые аналитические функции.
- •Групповая функция keep dense_rank.
- •Задача. Взятие последней записи о клиенте.
- •Задача. Отчет об изменениях зарплаты.
- •Задача. Пакет функций о вкладах.
- •Задача. Группировка лога выполнения процессов.
- •Задача. Вьюшка с аналитическими функциями по вкладам.
- •Задача. Календарь с аналитикой.
- •Задача. Поиск баланса счета на заданную дату.
- •Задача. Удаление исторических данных о рейтинге.
- •Функции, выдающие более одного значения.
- •Задача. Вызов многозначной функции.
- •"Расклейка" и "склейка" строк.
- •“Расклейка” одной строки.
- •“Расклейка” нескольких строк с группировкой.
- •“Склейка” в одну строку.
- •“Склейка” нескольких строк с группировкой.
- •Задача. Простая расклейка-склейка.
- •Задача. Скрипт создания индексов.
- •Задача. Скрипт создания таблиц.
- •Задача. Отчет о созданных объектах.
- •Задача. Отчет о числе строк в таблицах.
- •Задача. Расклейка списка хобби.
- •Задача. Склейка запроса о максимумах числовых полей.
- •Оптимизация запросов.
Задача. Триггер логирования dml-операций.
Дана таблица KK_16 и таблица KK_16_LOG, являющаяся логом изменений в KK_16. KK_16_LOG содержит два набора полей, имеющихся в KK_16, (для старых и новых значений), дополнительное поле OPERATION_CODE, принимающее одно из значений ('I','U','D'), и дополнительное поле OPERATION_DATE – дата операции.
Написать AFTER INSERT OR UPDATE OR DELETE триггер на таблицу KK_16, который добавляет в KK_16_LOG записи о том, что было в KK_16 вставлено, изменено (указать старые и новые значения полей) или удалено. В логе следует указывать тип операции ('I'-insert, 'U'-update, 'D'-delete) и дату SYSDATE, когда проведена логируемая операция.
Создадим таблицы:
create table KK_16
(
nickname VARCHAR2(50),
rating INTEGER,
reg_date DATE
);
create table KK_16_LOG
(
old_nickname VARCHAR2(50),
old_rating INTEGER,
old_reg_date DATE,
new_nickname VARCHAR2(50),
new_rating INTEGER,
new_reg_date DATE,
operation_code VARCHAR2(1),
operation_date DATE
);
Создадим решающий задачу триггер. Заметим, что commit в триггере не делаем, commit делается во внешней транзакции:
CREATE OR REPLACE TRIGGER KK_TRIG_AIUD_KK_16
AFTER INSERT OR UPDATE OR DELETE ON KK_16
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO KK_16_LOG
(OLD_NICKNAME,
OLD_RATING,
OLD_REG_DATE,
NEW_NICKNAME,
NEW_RATING,
NEW_REG_DATE,
OPERATION_CODE,
OPERATION_DATE)
VALUES
(NULL,
NULL,
NULL,
:NEW.NICKNAME,
:NEW.RATING,
:NEW.REG_DATE,
'I',
SYSDATE);
ELSIF UPDATING THEN
INSERT INTO KK_16_LOG
(OLD_NICKNAME,
OLD_RATING,
OLD_REG_DATE,
NEW_NICKNAME,
NEW_RATING,
NEW_REG_DATE,
OPERATION_CODE,
OPERATION_DATE)
VALUES
(:OLD.NICKNAME,
:OLD.RATING,
:OLD.REG_DATE,
:NEW.NICKNAME,
:NEW.RATING,
:NEW.REG_DATE,
'U',
SYSDATE);
ELSIF DELETING THEN
INSERT INTO KK_16_LOG
(OLD_NICKNAME,
OLD_RATING,
OLD_REG_DATE,
NEW_NICKNAME,
NEW_RATING,
NEW_REG_DATE,
OPERATION_CODE,
OPERATION_DATE)
VALUES
(:OLD.NICKNAME,
:OLD.RATING,
:OLD.REG_DATE,
NULL,
NULL,
NULL,
'D',
SYSDATE);
END IF;
END KK_TRIG_AIUD_KK_16;
Проверим работу триггера с помощью следующих операций:
INSERT INTO KK_16(NICKNAME, RATING, REG_DATE) VALUES('moloko', 31337, to_date('28.08.2004', 'DD.MM.YYYY'));
INSERT INTO KK_16(NICKNAME, RATING, REG_DATE) VALUES('razdvakr', 98798, to_date('09.06.2005', 'DD.MM.YYYY'));
INSERT INTO KK_16(NICKNAME, RATING, REG_DATE) VALUES('kokos', 7687, to_date('11.09.2011', 'DD.MM.YYYY'));
UPDATE KK_16 SET RATING = 346 WHERE NICKNAME = 'razdvakr';
UPDATE KK_16 SET NICKNAME = 'KOKOC', REG_DATE = to_date('12.10.2010', 'DD.MM.YYYY') WHERE RATING = 7687;
DELETE FROM KK_16 WHERE RATING = 31337;
Проверим результаты в логе:
SELECT * FROM KK_16_LOG;