- •Введение.
- •Соединение с бд 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.
- •Задача. Взятие последней записи о клиенте.
- •Задача. Отчет об изменениях зарплаты.
- •Задача. Пакет функций о вкладах.
- •Задача. Группировка лога выполнения процессов.
- •Задача. Вьюшка с аналитическими функциями по вкладам.
- •Задача. Календарь с аналитикой.
- •Задача. Поиск баланса счета на заданную дату.
- •Задача. Удаление исторических данных о рейтинге.
- •Функции, выдающие более одного значения.
- •Задача. Вызов многозначной функции.
- •"Расклейка" и "склейка" строк.
- •“Расклейка” одной строки.
- •“Расклейка” нескольких строк с группировкой.
- •“Склейка” в одну строку.
- •“Склейка” нескольких строк с группировкой.
- •Задача. Простая расклейка-склейка.
- •Задача. Скрипт создания индексов.
- •Задача. Скрипт создания таблиц.
- •Задача. Отчет о созданных объектах.
- •Задача. Отчет о числе строк в таблицах.
- •Задача. Расклейка списка хобби.
- •Задача. Склейка запроса о максимумах числовых полей.
- •Оптимизация запросов.
Задача. Триггер контроля.
Дана таблица курсов валют. Необходимо написать триггер, который с помощью raise_application_error выдает информационные ошибки при некорректных изменениях (insert, update, delete) в таблице курсов, которые осуществляет пользователь из интерфейса:
- при вставке нулевого или отрицательного курса
- при отсутствии в записи одного из полей (даты, валюты, курса)
- при удалении записи о курсе
Создадим таблицу курсов:
CREATE TABLE KK_RATE
(
RATE_DATE DATE,
CURRENCY_CODE INTEGER,
RATE NUMBER(6,2)
);
Создадим триггер контроля:
create or replace trigger trig_biud_rate
before insert or update or delete on kk_rate
for each row
begin
if inserting or updating then
-- запрет неположительных курсов
if :new.rate <= 0 then
raise_application_error(-20001,
'Курс должен быть строго положительным');
end if;
-- запрет null-значений
if :new.rate_date is null or :new.currency_code is null or
:new.rate is null then
raise_application_error(-20002, 'Заполните все поля');
end if;
elsif deleting then
-- запрет удаления
raise_application_error(-20003,
'Нельзя удалять курсы');
end if;
end trig_biud_rate;
Диапазон пользовательских кодов ошибок, генерируемых с помощью raise_application_error: от -20000 до -20999.
Проверим работу триггера, будем выполнять команды по одной:
insert into kk_rate(rate_date, currency_code, rate) values(to_date('21.06.2012','dd.mm.yyyy'), 840, 32.91);
insert into kk_rate(rate_date, currency_code, rate) values(to_date('22.06.2012','dd.mm.yyyy'), 840, 32.91);
insert into kk_rate(rate_date, currency_code, rate) values(to_date('23.06.2012','dd.mm.yyyy'), 978, -41.72);
update kk_rate set rate = 0 where rate_date = to_date('22.06.2012','dd.mm.yyyy') and currency_code = 840;
insert into kk_rate(rate_date, currency_code, rate) values(to_date('23.06.2012','dd.mm.yyyy'), 978, null);
insert into kk_rate(rate_date, currency_code, rate) values(null, 978, 76.92);
delete from kk_rate where rate_date = to_date('22.06.2012','dd.mm.yyyy') and currency_code = 840;
delete from kk_rate;
Также можно самомтоятельно разобрать статью:
http://www.sql.ru/faq/faq_topic.aspx?fid=513
Global temporary tables и переменные в заголовке пакета.
Global temporary tables.
Иногда необходимо в нескольких сессиях использовать одну и ту же таблицу, но при этом хранить в ней различные данные для каждой сессии. Для таких целей существуют временные таблицы - global temporary tables. Например, временные таблицы нужны для складирования промежуточных рассчетов отчета, который разные пользователи одновременно запускают в разных сессиях с различными параметрами.
Создадим временную таблицу:
create global temporary table TMP_TABLE_D(ID NUMBER)
on commit delete rows;
Опция 'on commit delete rows' означает, что после commit-а в сессии все строки из таблицы автоматически удаляются.
Если бы стояла опция 'on commit preserve rows', то после commit-а в сессии строки таблицы сохранялись бы неизменными.
Выполним в двух различных сессиях один и тот же блок кода. Во временную таблицу вставляются сгенерированные случайные значения, а затем в dbms_output выдается среднее значение вставленных id:
declare
avg_id number;
begin
for i in 1 .. 1000 loop
insert into tmp_table_d (id) values (1000 * dbms_random.value());
end loop;
select avg(id) into avg_id from tmp_table_d;
dbms_output.put_line('avg_id = ' || to_char(avg_id, '999.99'));
end;
В каждой из сессий данные в tmp_table_d получатся различные и значения avg_id вряд ли совпадут. Можно посмотреть эти данные запросом:
select * from tmp_table_d;
После выполнение команды
commit;
все данные в tmp_table_d исчезают, как, впрочем, исчезают и при logoff-е сессии.
