Основы PL/SQL

Схема БД. Её объекты

Понятие схемы БД

Схема - это совокупность всех объектов некоего пользователя, называемого владельцем схемы. Сюда входят таблицы, индексы, представления, триггеры, всё-всё-всё. То есть мы должны понимать, что когда мы говорим про функции или процедуры в PL/SQL, они находятся внутри схемы.

Мы не будем перечислять все возможные типы объектов, которые могут храниться в схеме, перечислим лишь несколько. Все нижеописанные объекты будут рассмотрены по отдельности далее в учебнике, здесь будет дана информация для первичного ознакомления с ними.

Функции

Функции представляют собой именованные блоки кода, которые можно вызывать повторно. Отличительной особенностью функций является то, что по своей натуре они должны возвращать некое значение.

Простой пример - функция сложения двух чисел Mysum. Вот пример того, как она могла бы быть описана:

function Mysum(a number,
    b number
) return number
is
begin
    return a + b;
end;

И далее, везде, где мы хотим получить сумму двух чисел, мы можем использовать уже созданную функцию:

begin
    a := sum(5, 10);
    b := sum(10, a);
    -- Функции могут использоваться в качестве
    -- параметров других функций
    c := sum(sum(a, b), 20);
end;

Также, функции pl/sql можно использовать в обычных SQL запросах, например вот так:

select Mysum(l.age, 2) new_age
from users l

Процедуры

Процедуры, так же как и функции, представляют собой именованные блоки кода, которые можно(и нужно) использовать повторно. Отличаются от функций тем, что вызов процедуры не возвращает значение, как функция, но несмотря на это, через процедуры можно возвращать значения - через так называемые out параметры.

Процедуры нельзя использовать в SQL запросах.

Процедура или функция

Процедуры очень похожи на функции, и не всегда можно понять, что же использовать. Тем не менее, в большинстве случаев, рекомендуется использовать функции лишь для того, чтобы что-то вычислять и возвращать это значение, но не изменять состояние данных в БД. Процедуры же, наоборот, рекомендуется использовать в тех случаях, когда они изменяют данные в БД.

Вышеупомянутая функция Mysum, например, ничего не изменяет, она лишь считает сумму двух чисел и возвращает ее.

Какой код можно было бы использовать в процедуре? Ну, например, процедура добавления нового пользователя в систему. Добавление нового пользователя приводит к тому, что в таблицу(или даже несколько) БД будет добавлена запись, некоторые, возможно будут обновлены и т.д.

Итого, лучше создавать функцию, если:

Лучше создавать процедуру, если:

Конечно, эти советы не являются обязательными, и от них вполне можно отступаться, более того, достаточно часто в коде PL/SQL можно встретить функции, которые изменяют данные, например, подобного рода:

-- добавить пользователя и вернуть его id
function addUser(login varchar2) return number;

Здесь функция addUser добавляет нового пользователя в систему и сразу возвращает его id.

Главное, пожалуй, здесь то, чтобы действия, производимые подпрограммами, которые вы пишете, должны быть понятными; достичь этого во многом помогают правильные наименования, как в примере выше - вот если бы функция называлась бы просто user, было бы гораздо сложнее понять, что она делает.

Процедуры и функции, которые хранятся в БД, еще часто называют хранимыми процедурами и хранимыми функциями. Тем не менее, чаще всего используют термин “хранимая процедура” для обозначения как процедур, так и функций.

Пакеты

Пакеты - это такие объекты, которые позволяют сгруппировать набор функций, процедур, констант, переменных и типов в одном модуле. Они не только помогают улучшить организацию кода, но и позволяют реализовать инкапсуляцию - т.е. скрыть внутреннюю реализацию своего функционала. Достигается это благодаря тому, что пакет имеет спецификацию и тело. Для использования внутри схемы доступны всё, что описано в спецификации пакета, но все, что описано в теле пакета и не описано в спецификации, нельзя использовать вне тела пакета.

Приведем простой пример: предположим, у нас есть пакет под названием pckUser. В спецификации пакета даны описания функций добавления, удаления и редактирования пользователя:

procedure insUser(login varchar2);
procedure updUser(id number, login varchar2);
procedure delUser(id number);

Эти три процедуры будут доступны внутри схемы, и вызвать их можно будет подобным образом:

begin
    pckUser.insUser('username');
end;

Схематично структура пакета может выглядеть подобным образом:

“Снаружи” из пакета доступны только три вышеупомянутые процедуры. Но внутри пакета, помимо реализации публичных процедур, также созданы еще две функции - isLoginExist и updUserStatus. Они могут использоваться как вспомогательные функции/процедуры внутри других подпрограммах пакета, но не будут доступны для вызова вне тела пакета.

Триггеры

Триггеры - это специальные процедуры, которые запускаются автоматически при определенных действиях с таблицами.

То есть, когда мы запускаем, к примеру, следующий запрос:

update users
set is_active = 0
where id = 10

В базе данных может автоматически запуститься триггер, который будет при деактивации пользователя заполнять значение в колонке с датой деактивации.

Триггеры могут выполняться до или после вставки, изменения или удаления данных в таблице. Существуют и более сложные виды триггеров, но они будут рассматриваться в отдельной теме, посвященной триггерам.