- •Введение.
- •Соединение с бд 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.
- •Задача. Взятие последней записи о клиенте.
- •Задача. Отчет об изменениях зарплаты.
- •Задача. Пакет функций о вкладах.
- •Задача. Группировка лога выполнения процессов.
- •Задача. Вьюшка с аналитическими функциями по вкладам.
- •Задача. Календарь с аналитикой.
- •Задача. Поиск баланса счета на заданную дату.
- •Задача. Удаление исторических данных о рейтинге.
- •Функции, выдающие более одного значения.
- •Задача. Вызов многозначной функции.
- •"Расклейка" и "склейка" строк.
- •“Расклейка” одной строки.
- •“Расклейка” нескольких строк с группировкой.
- •“Склейка” в одну строку.
- •“Склейка” нескольких строк с группировкой.
- •Задача. Простая расклейка-склейка.
- •Задача. Скрипт создания индексов.
- •Задача. Скрипт создания таблиц.
- •Задача. Отчет о созданных объектах.
- •Задача. Отчет о числе строк в таблицах.
- •Задача. Расклейка списка хобби.
- •Задача. Склейка запроса о максимумах числовых полей.
- •Оптимизация запросов.
Раздача прав (grants).
Для разграничений прав доступа к объектам текущей схемы для других пользователей используется раздача прав доступа с помощью команды grant. Забрать права можно командой revoke.
Допустим, мы залогинены в схеме SCHEME1, в которой есть таблица TAB1 и пакет(или процедура, функция) PKG1. Имеется схема SCHEME2, которой мы раздаем права:
Grant select on SCHEME1.TAB1 to SCHEME2; /*Дать права на SELECT из таблицы TAB1*/
Grant insert, update, delete on SCHEME1.TAB1 to SCHEME2; /*Дать права на insert, update, delete таблицы TAB1*/
Revoke insert, update, delete on SCHEME1.TAB1 from SCHEME2; /*Забрать права на insert, update, delete таблицы TAB1*/
Grant alter on SCHEME1.TAB1 to SCHEME2; /*Дать права на alter таблицы TAB1*/
Grant all on SCHEME1.TAB1 to SCHEME2; /*Дать все права на таблицу TAB1*/
Grant execute on SCHEME1.PKG1 to SCHEME2; /*Дать права на выполнение PKG1*/
Grant create database link to SCHEME2; /*Дать права создавать database link*/
Операции над множествами, joins.
Продемонстрируем операции над множествами:
Создадим две таблицы одинаковой структуры:
CREATE TABLE KK_T1 AS
SELECT 1 VAL FROM DUAL
UNION ALL
SELECT 2 VAL FROM DUAL;
CREATE TABLE KK_T2 AS
SELECT 2 VAL FROM DUAL
UNION ALL
SELECT 3 VAL FROM DUAL;
Объединение с убиранием дубликатов:
SELECT VAL FROM KK_T1
UNION
SELECT VAL FROM KK_T2;
Объединение без убирания дубликатов:
SELECT VAL FROM KK_T1
UNION ALL
SELECT VAL FROM KK_T2;
Разность множеств, KK_T1 \ KK_T2:
SELECT VAL FROM KK_T1
MINUS
SELECT VAL FROM KK_T2;
Пересечение множеств, KK_T1 ∩ KK_T2:
SELECT VAL FROM KK_T1
INTERSECT
SELECT VAL FROM KK_T2;
Задача. Сравнение множеств.
Даны таблицы KK_STUDENTS_2010 и KK_STUDENTS_2012 со списками студентов за 2010 год и 2012 год.
С 2010 года по 2012 год некоторых студентов выпустили, приняли некоторых новых студентов, некоторые продолжают обучение.
Требуется создать отчет вида
NAME |
WAS_STUDENT_IN_2010 |
WAS_STUDENT_IN_2012 |
ИВАНОВ |
N |
Y |
ТРУНОВ |
Y |
Y |
ДРОНОВ |
Y |
Y |
ШТАНОВ |
Y |
N |
двумя способами
- UNION, MINUS, INTERSECT;
- FULL OUTER JOIN.
Создадим таблицы, заполним их данными:
CREATE TABLE KK_STUD_2010(ID INTEGER, NAME VARCHAR2(30));
CREATE TABLE KK_STUD_2012(ID INTEGER, NAME VARCHAR2(30));
INSERT INTO KK_STUD_2010(ID, NAME) VALUES(2,'ТРУНОВ');
INSERT INTO KK_STUD_2010(ID, NAME) VALUES(3,'ДРОНОВ');
INSERT INTO KK_STUD_2010(ID, NAME) VALUES(4,'ШТАНОВ');
INSERT INTO KK_STUD_2012(ID, NAME) VALUES(1,'ИВАНОВ');
INSERT INTO KK_STUD_2012(ID, NAME) VALUES(2,'ТРУНОВ');
INSERT INTO KK_STUD_2012(ID, NAME) VALUES(3,'ДРОНОВ');
Первое решение:
(
SELECT ID, NAME, 'Y' AS WAS_IN_2010, 'N' AS WAS_STUDENT_IN_2012 FROM KK_STUD_2010
MINUS
SELECT ID, NAME, 'Y' AS WAS_IN_2010, 'N' AS WAS_STUDENT_IN_2012 FROM KK_STUD_2012
)
UNION
(
SELECT ID, NAME, 'Y' AS WAS_IN_2010, 'Y' AS WAS_STUDENT_IN_2012 FROM KK_STUD_2010
INTERSECT
SELECT ID, NAME, 'Y' AS WAS_IN_2010, 'Y' AS WAS_STUDENT_IN_2012 FROM KK_STUD_2012
)
UNION
(
SELECT ID, NAME, 'N' AS WAS_IN_2010, 'Y' AS WAS_STUDENT_IN_2012 FROM KK_STUD_2012
MINUS
SELECT ID, NAME, 'N' AS WAS_IN_2010, 'Y' AS WAS_STUDENT_IN_2012 FROM KK_STUD_2010
);
Второе решение:
SELECT NVL(KK_STUD_2010.ID, KK_STUD_2012.ID) ID,
NVL(KK_STUD_2010.NAME, KK_STUD_2012.NAME) NAME,
DECODE(KK_STUD_2010.ID, NULL, 'N', 'Y') AS WAS_STUDENT_IN_2010,
DECODE(KK_STUD_2012.ID, NULL, 'N', 'Y') AS WAS_STUDENT_IN_2012
FROM KK_STUD_2010
FULL OUTER JOIN KK_STUD_2012
ON KK_STUD_2010.ID = KK_STUD_2012.ID;
Второе решение быстрее, т.к. не сканирует таблицы несколько раз. Кроме того, второе решение демонстрирует эффективный способ выявления дельты (порции изменившихся данных) между двумя загрузками.
