
- •Введение.
- •Соединение с бд 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.
- •Задача. Взятие последней записи о клиенте.
- •Задача. Отчет об изменениях зарплаты.
- •Задача. Пакет функций о вкладах.
- •Задача. Группировка лога выполнения процессов.
- •Задача. Вьюшка с аналитическими функциями по вкладам.
- •Задача. Календарь с аналитикой.
- •Задача. Поиск баланса счета на заданную дату.
- •Задача. Удаление исторических данных о рейтинге.
- •Функции, выдающие более одного значения.
- •Задача. Вызов многозначной функции.
- •"Расклейка" и "склейка" строк.
- •“Расклейка” одной строки.
- •“Расклейка” нескольких строк с группировкой.
- •“Склейка” в одну строку.
- •“Склейка” нескольких строк с группировкой.
- •Задача. Простая расклейка-склейка.
- •Задача. Скрипт создания индексов.
- •Задача. Скрипт создания таблиц.
- •Задача. Отчет о созданных объектах.
- •Задача. Отчет о числе строк в таблицах.
- •Задача. Расклейка списка хобби.
- •Задача. Склейка запроса о максимумах числовых полей.
- •Оптимизация запросов.
Задача. Группировка лога выполнения процессов.
Дана таблица лога начала и окончания выполнения процессов kk_log (id number, lc_date date, lc_message varchar2(200)).
В таблицу пишутся записи вида 'start <процесс>' и 'finish <процесс>'.
Написать запрос о том, какой процесс в какое время начинался, в какое время заканчивался и сколько минут работал.
Создадим таблицу и заполним ее данными посложнее:
create table kk_log (id number, lc_date date, lc_message varchar2(200));
insert into kk_log (id,lc_date,lc_message) values (1,to_date('27.06.2012 0:55:47','dd.mm.yyyy hh24:mi:ss'), 'start Pump_Pers_PercStav2');
insert into kk_log (id,lc_date,lc_message) values (2,to_date('27.06.2012 1:56:00','dd.mm.yyyy hh24:mi:ss'), 'start Fill_depfis_pays');
insert into kk_log (id,lc_date,lc_message) values (3,to_date('27.06.2012 1:56:12','dd.mm.yyyy hh24:mi:ss'), 'finish Pump_Pers_PercStav2');
insert into kk_log (id,lc_date,lc_message) values (4,to_date('27.06.2012 1:56:28','dd.mm.yyyy hh24:mi:ss'), 'finish Fill_depfis_pays');
insert into kk_log (id,lc_date,lc_message) values (5,to_date('27.06.2012 8:06:39','dd.mm.yyyy hh24:mi:ss'), 'start Failing_process_which_not_finishes');
insert into kk_log (id,lc_date,lc_message) values (6,to_date('27.06.2012 9:02:33','dd.mm.yyyy hh24:mi:ss'), 'start Pump_Prep_PersLim');
insert into kk_log (id,lc_date,lc_message) values (7,to_date('27.06.2012 9:03:44','dd.mm.yyyy hh24:mi:ss'), 'start Fill_depfis_pays');
insert into kk_log (id,lc_date,lc_message) values (8,to_date('27.06.2012 9:04:07','dd.mm.yyyy hh24:mi:ss'), 'finish Fill_depfis_pays');
insert into kk_log (id,lc_date,lc_message) values (9,to_date('27.06.2012 9:04:07','dd.mm.yyyy hh24:mi:ss'), 'start Fill_depfis_pays');
insert into kk_log (id,lc_date,lc_message) values (10,to_date('27.06.2012 9:04:07','dd.mm.yyyy hh24:mi:ss'), 'finish Fill_depfis_pays');
insert into kk_log (id,lc_date,lc_message) values (11,to_date('27.06.2012 9:04:07','dd.mm.yyyy hh24:mi:ss'), 'start Pump_Pers_PercStav2');
insert into kk_log (id,lc_date,lc_message) values (12,to_date('27.06.2012 9:06:19','dd.mm.yyyy hh24:mi:ss'), 'finish Pump_Prep_PersLim');
insert into kk_log (id,lc_date,lc_message) values (13,to_date('27.06.2012 9:56:16','dd.mm.yyyy hh24:mi:ss'), 'start Failing_process_which_not_finishes');
insert into kk_log (id,lc_date,lc_message) values (14,to_date('27.06.2012 10:11:54','dd.mm.yyyy hh24:mi:ss'), 'finish Pump_Pers_PercStav2');
insert into kk_log (id,lc_date,lc_message) values (15,to_date('27.06.2012 11:08:41','dd.mm.yyyy hh24:mi:ss'), 'start Pump_cats');
В подзапросе q1 вычленим из лога название процесса и индикатор начала или окончания процесса (0 или 1 соответственно).
В подзапросе q2 с помощью функции lead найдем для каждой записи о процессе следующую запись, сортируя данные по id. Здесь же вычисляем lead_indicator, чтобы особо учесть случаи, когда после start идет не finish, а снова start (например, потому, что процесс не завершился успешно и был запущен повторно).
Наконец, во внешнем запросе отсечем записи по условию indicator = 0 и вычислим время выполнения каждого процесса в секундах:
select proc_name,
start_date,
decode(lead_indicator, 1, finish_date, null) finish_date,
(decode(lead_indicator, 1, finish_date, null) - start_date) * 60 * 60 * 24 run_time_in_seconds
from (select id,
lc_date start_date,
lead(lc_date) over(partition by proc_name order by id) finish_date,
proc_name,
indicator,
lead(indicator) over(partition by proc_name order by id) lead_indicator
from (select id,
lc_date,
trim(substr(lc_message, 7)) proc_name,
decode(substr(lc_message, 1, 6),
'start ',
0,
'finish',
1) indicator
from kk_log) q1) q2
where indicator = 0
order by start_date, finish_date;