- •1.Традиционные файловые системы
- •1.1.Подход, используемый в файловых системах
- •2.Системы с базами данных
- •2.1.База данных
- •2.2.Система управления базами данных ─ субд
- •2.3.Разработка базы данных смена парадигмы
- •3.Преимущества и недостатки субд
- •4.Модели данных
- •4.1.Объектные модели данных
- •4.2.Модели данных на основе записей
- •4.2.1 Иерархическая модель данных
- •4.2.2 Сетевая модель данных
- •4.2.3 Реляционная модель данных
- •4.2.4 Свойства отношений
- •4.2.5 Реляционная целостность
- •Целостность сущностей
- •Ссылочная целостность
- •Корпоративные ограничения целостности.
- •5.Функции субд
- •6.Компоненты субд
- •7.Системные каталоги
- •8.Инструкции sql
- •8.1.Имена
- •8.2.Имена таблиц
- •8.3.Имена столбцов
- •8.4.Типы данных
- •8.5.Константы
- •9.Инструкция select
- •9.1.Предложение select
- •9.2.Предложение from
- •9.3.Результаты запроса на выборку
- •9.4.Простые запросы
- •9.5.Вычисляемые столбцы
- •9.6.Выборка всех столбцов
- •9.7.Повторяющиеся строки
- •9.8.Отбор строк (предложение where)
- •9.8.1 Сравнение
- •9.8.2 Проверка на принадлежность значений (оператор between and)
- •9.8.3 Проверка на членство в множестве (оператор in)
- •9.8.4 Проверка на соответствие шаблону (оператор like)
- •10.Запросы с объединением таблиц
- •10.1.Производительность при обработке многотабличных запросов
- •11.Статистические (агрегатные) функции
- •12.Запросы с группировкой (предложение group by)
- •12.1.Условие отбора групп (предложение having)
- •13.Подчиненные запросы (подзапросы)
- •13.1.Условия отбора в подчиненном запросе
- •13.1.1 Проверка на существование (предикат exists)
- •13.1.2 Многократное сравнение (предикаты any и all)
- •Предикат any
- •Предикат all
- •13.1.3 Уровни вложенности запросов
- •14.Представления
- •14.1.Создание представлений
- •14.2.Как субд работает с представлениями
- •14.3.Преимущества представлений
- •14.4.Недостатки представлений
- •14.5.Обновление представлений
- •14.6.Контроль над обновлением представлений (предложение with check option)
- •15.Добавление новых данных
- •15.1.Однострочная инструкция insert
- •15.2.Добавление значений null
- •15.3.Добавление всех столбцов
- •15.4.Многострочная инструкция insert
- •16.Удаление существующих данных
- •16.1.Удаление всех строк
- •16.2.Инструкция delete с подчиненным запросом
- •17.Обновление существующих данных
- •17.1.Обновление всех строк
- •17.2.Инструкции update с подчиненным запросом
- •18.Условия целостности данных
- •18.1.Обязательное наличие данных
- •18.2.Условия на значения
- •18.3.Целостность таблиц (сущностей)
- •18.4.Проблемы, связанные со ссылочной целостностью
- •18.5.Правила удаления и обновления
- •18.6.Каскадные удаления
- •18.7.Ссылочные циклы
- •19.Язык определения данных
- •19.1.Создание базы данных
- •19.2.Создание таблиц (инструкция create table)
- •19.2.1 Определения столбцов
- •19.2.2 Определение первичного и внешнего ключей
- •19.2.3 Условия уникальности и ограничения на значения столбцов
- •19.3.Удаление таблицы (инструкция drop table)
- •19.4.Изменение определения таблицы (инструкция alter table)
- •19.4.1 Добавление и удаление столбца
- •19.4.2 Изменение первичных и внешних ключей
- •20.Псевдонимы таблиц (инструкции create / drop synonym)
- •21.Индексы (инструкции create/drop index)
- •22.Транзакции
- •22.1.Инструкции commit и rollback
- •22.2.Модель транзакции в стандарте ansi/iso
- •22.3.Журнал транзакций
- •22.4.Транзакции и работа в многопользовательском режиме
- •22.4.1 Проблема пропавшего обновления
- •22.4.2 Проблема промежуточных данных
- •22.4.3 Проблема несогласованных данных
- •22.4.4 Проблема строк – призраков
- •22.5.Параллельные транзакции
- •22.6.Блокировка
- •22.6.1 Уровни блокировки
- •22.6.2 Жесткая и нежесткая блокировки
- •22.6.3 Тупиковые ситуации
- •22.6.4 Явная блокировка
- •23.Принципы защиты данных, применяемые в sql
- •23.1.Пользователи
- •23.1.1 Аутентификация пользователей
- •23.2.Защищаемые объекты
- •23.3.Привилегии
- •23.3.1 Работа с привилегиями при помощи ролей
- •23.3.2 Роли, определяемые пользователями
- •23.3.3 Разрешение и запрещение ролей
- •23.3.4 Предоставление привилегий (инструкция grant)
- •23.3.5 Передача привилегий (предложение with grant option)
- •23.3.6 Отмена привилегий (инструкция revoke)
- •Инструкция revoke и право предоставления привилегий
- •24.Программирование сервера баз данныхoracle посредством pl/sql
- •24.1.Блоки
- •24.2.Комментарии
- •24.3.Объявления
- •24.3.1 Переменные и константы
- •24.3.2 Подтипы, определяемые пользователями
- •24.3.3 Составные типы, определяемые пользователями
- •Вложенные таблицы
- •Изменяемые массивы
- •24.3.4 Атрибуты
- •24.3.5 Особые замечания относительно вложенных таблиц и изменяемых массивов
- •Инициализация вложенных таблиц и изменяемых массивов
- •Использование методов сборных конструкций со вложенными таблицами и с изменяемыми массивами
- •24.3.6 Курсоры, курсорные типы и курсорные переменные
- •Курсорные типы и переменные
- •24.4.Функциональные возможности программ
- •24.4.1 Управление выполнением программ
- •Условное управление
- •Итерационное управление
- •24.4.2 Взаимодействие с базами данных
- •Стандартный dml
- •Работа с курсорами
- •Работа с курсорными переменными
- •24.4.3 Обработка исключительных ситуаций
- •24.5.Типы программ pl/sql
- •24.5.1 Анонимные блоки
- •24.5.2 Хранимые процедуры и функции
- •Создание процедур
- •Создание функций
- •Вызов процедур и функций
- •Управление блоками в sql*Plus
- •24.5.3 Модули
- •Использование объектов модуля
- •24.5.4 Триггеры баз данных
- •24.6.Служебные модули oracle
- •24.6.1 Модуль dbms_output
- •24.6.2 Динамический sql
- •Модуль dbms_sql
- •Использование dbms_sql
- •24.6.3 Файловый ввод/вывод (модуль utl_file)
- •Безопасность
- •Безопасность базы данных
- •Безопасность операционной системы
- •Исключительные ситуации, устанавливаемые в utl_file
- •Открытие и закрытие файлов
- •Файловый вывод
- •Файловый ввод
- •24.6.4 Взаимодействие между соединениями (модуль dbms_pipe)
- •Посылка сообщений
- •Получение сообщений
- •Создание программных каналов и управление ими
- •Программные каналы
- •Общие и частные каналы
- •Привилегии и безопастность
- •Установление протокола связи
- •Форматирование сообщений
- •Адресация данных
- •25.Создание приложений баз данных средствами odbc
- •25.1.Архитектура odbc
- •25.2.Коды возврата
- •25.3.Основной алгоритм программ odbc
- •25.4.Функции инициализации и завершения
- •25.5.Выполнение операторов
- •25.5.1 Функции управления каталогом
- •25.5.2 Непосредственное выполнение
- •25.5.3 Подготавливаемое выполнение
- •Использование параметров при выполнении.
- •25.6.Выборка результатов.
- •25.6.1 Выборка информации о результирующем множестве
- •25.6.2 Базовые функции выборки данных
- •25.7. Подробный алгоритм использования odbc в прикладных программах
Использование dbms_sql
ОБРАБОТКА ОПЕРАТОРОВ DML ПОСРЕДСТВОМ DBMS_SQL. Для обработки операторов UPDATE, DELETE, INSERT средствами модуля DBMS_SQL необходимо последовательно выполнить следующие действия:
Открыть курсор.
Осуществляется посредством вызова процедуры OPEN_CURSOR, описание которой в модуле выглядит следующим образом:
OPEN_CURSOR return integer;
Параметры в данной процедуре отсутствуют.
Каждый вызов возвращает целое число, представляющее собой идентификационный номер курсора. Этот номер используется в последующих вызовах курсора. В границах одного курсора можно по очереди обрабатывать несколько SQL – операторов или выполнять один и тот же оператор несколько раз.
Выполнить грамматический разбор оператора.
При выполнении грамматического разбора оператор направляется на сервер БД. Сервер проверяет его синтаксис и семантику и возвращает ошибку (устанавливая исключительную ситуацию), если нарушены требования грамматики. Кроме того, во время разбора определяется план выполнения оператора. Осуществляется грамматический разбор посредством вызова процедуры DBMS_SQL.PARSE, описание которой в модуле имеет следующий вид:
procedure PARSE (c in integer, statement in varchar2, language_flag in integer).
Здесь с – идентификационный номер курсора, предварительно должен быть открыт посредством OPEN_CURSOR, STATEMENT – оператор, грамматический разбор которого выполняется, LANGUAGE FLAG – указывает, как трактовать оператор, значение NATIVE – режим установленный для той базы данных, с которой выполнено соединение.
Привязка входных переменных
При выполнении этой операции, заполнители, указанные в нем связываются с фактическими переменными. Имена заполнители обычно предваряют символом двоеточия. Процедура BIND_VARIABLE выполняет привязку и объявление имен заполнителей. Размер и тип данных фактических переменных также устанавливается BIND_VARIABLE посредством набора переопределенных вызовов:
procedure BIND_VARIABLE (c in integer, name in varchar2, value in number),
procedure BIND_VARIABLE (c in integer, name in varchar2,value in varchar2),
procedure BIND_VARIABLE (c in integer, name in varchar2, value in varchar2,
out_value_size in integer).
Здесь параметр NAME – это имя заполнителя, с которым будет связана переменная, VALUE – реальные данные, которые будут привязываться, тип и размер этой переменной также считываются. При необходимости данные, содержащиеся в этой переменной, будут преобразованы. Параметр OUT_VALUE_SIZE – параметр, задаваемый при привязке переменных varchar2 и char; если указан, то это максимальный ожидаемый размер значения в байтах, если не указан, то используется размер, указанный в параметре VALUE.
Выполнение оператора.
Осуществляется посредством функции EXECUTE. Описание её в модуле выглядит следующим образом:
function EXECUTE (c in integer) return integer;
Здесь с – идентификатор предварительно открытого курсора.
Функция EXECUTE возвращает число отработанных строк (в этом смысле возвращаемое значение аналогично курсорному атрибуту %ROWCOUNT). Следует учесть, что возвращаемое значение не определено для операторов выборки, а также и то, что EXECUTE вызывается из выражений программ.
Закрытие курсора
Закрытие курсора осуществляется посредством вызова процедуры CLOSE_CURSOR, описание которой выглядит следующим образом:
procedure CLOSE_CURSOR (c in out integer).
Передаваемое процедуре значение должно быть достоверным идентификатором курсора. После вызова фактический параметр устанавливается в NULL , что свидетельствует о закрытии курсора.
Приведем пример:
create or replace procedure update_address (p_lname in staff.lname %type,
p_fname in staff.fname %type,
p_newaddress in staff.address %type,
p_rowsupdated out integer) is
v_cursor_id integer;
v_updatestmt varchar2(100);
begin
v_cursor_id := DBMS_SQL.OPEN_CURSOR;
v_updatestmt := ‘update staff
set address =:na
where fname=:fname and lname=:lname’;
DBMS_SQL.PARSE (v_cursor_id, v_updatestmt, DBMS_SQL.NATIVE);
DBMS_SQL.BIND_VARIABLE (v_cursor_id, :na, p_newaddress);
DBMS_SQL.BIND_VARIABLE (v_cursor_id, :fname, p_fname);
DBMS_SQL.BIND_VARIABLE (v_cursor_id, :lname, p_lname);
p_rowsupdated:= DBMS_SQL.EXECUTE (v_cursor_id);
DBMS_SQL.CLOSE_CURSOR(v_cursor_id);
exception
when others then
DBMS_SQL.CLOSE_CURSOR(v_cursor_id);
raise;
end update_address;
ОБРАБОТКА ЗАПРОСОВ НА ИЗВЛЕЧЕНИЕ ИНФОРМАЦИИ. Производится путем последовательного выполнения всех ниже перечисленных действий:
Открытие курсора (OPEN_CURSOR),
Выполнение грамматического разбора (PARSE),
Выполнение привязки всех входных переменных (BIND_VARIABLE),
Описание элементов списка выбора (DEFINE_COLUMN),
Исполнения запроса (EXECUTE),
Считывания строк (FETCH),
Запись результатов в переменные (COLUMN_VALUE),
Закрытие курсора (CLOSE_CURSOR).
Как видно для динамического выполнения запросов необходимо использовать вызовы тех же процедур модуля DBMS_SQL, что и при выполнении инструкций DML, за исключением DEFINE_COLUMN, FETCH и COLUMN_VALUE. Рассмотрим подробнее как использовать эти процедуры.
Определение элементов списка выбора напоминает процесс привязки входных переменных, за исключением того, что элементы списка выбора должны быть не привязаны, а только определены. В процедуре DEFINE_COLUMN указываются типы и размер переменных, в которые считываются элементы списка выбора. Каждый элемент при этом преобразуется в тип соответствующей переменной.
procedure DEFINE_COLUMN (c in integer, position in integer, column in
number),
procedure DEFINE_COLUMN (c in integer, position in integer,column in
varchar2, column_size in integer).
Для переменных VARCHAR2 нужно обязательно указывать параметр COLUMN_SIZE, поскольку система поддержки PL/SQL должна знать максимальный размер этих переменных во время выполнения программы, так как в отличие от NUMBER, DATE данные этих типов не имеют фиксированной длины, заранее известной компилятору. Тип и предназначение параметров процедуры DEFINE_COLUMN приведены в таблице 5.
Таблица 5 Параметры DEFINE_COLUMN
Параметр |
Тип |
Предназначение |
с |
integer |
Идентификатор курсора. |
position |
integer |
Позиция пункта списка выбора. |
column |
number, varchar2 |
Переменная, определяющая тип и размер выходной переменной. Имя переменной не играет особой роли, однако тип и размер важны. Однако как в DEFINE_COLUMN, так и в COLUMN_VALUE обычно используются одни и те же переменные. |
column_size |
integer |
Максимальный ожидаемый размер данных. Обязателен для тех типов, длина которых не известна заранее системе поддержки PL/SQL. |
Считывание строк: строки набора запроса считываются в буфер посредством вызова функции FETCH_ROWS. Функция описана в модуле следующим образом:
function FETCH_ROWS (c in integer) return integer.
FETCH_ROWS возвращает число считываемых строк. FETCH_ROWS и COLUMN_VALUE вызывают в цикле несколько раз до тех пор, пока FETCH_ROWS не возвратит нуль.
Для записи результатов в переменные PL/SQL следует вызывать процедуру COLUMN_VALUE. Эта процедура вызывается после успешного выполнения FETCH_ROWS. Если в выборке не были возвращены строки, (что указывается возвратом 0 функцией FETCH_ROWS) COLUMN_VALUE устанавливает для выходной переменной NULL – значение. Ниже приведено описание процедуры в модуле DBMS_SQL:
procedure COLUMN_VALUE (c in integer, position in integer, value out
number);
procedure COLUMN_VALUE (c in integer, position in integer, value out number,
column_error out number,
actual_length out number);
procedure COLUMN_VALUE (c in integer, position in integer, value out
varchar2),
procedure COLUMN_VALUE (c in integer, position in integer, value out varchar2, column_error out number, actual_length out number).
Тип и предназначение параметров процедуры COLUMN_VALUE приведены в таблице 6.
Таблица 6 Параметры процедуры COLUMN_VALUE
Параметр |
Тип |
Предназначение |
1 |
2 |
3 |
с |
integer |
Идентификатор курсора. |
position |
integer |
Относительная позиция в списке выбора, как и в DEFINE_COLUMN, позиция первого элемента списка =1. |
|
|
|
|
|
Продолжение таблицы 6 |
1 |
2 |
3 |
value |
number, varchar2 |
Выходная переменная, если тип этого параметра отличается от типа, указанного в DEFINE_COLUMN то возникает ошибка, что соответствует исключительной ситуации DBMS_SQL.INCONSISTENT_TYPES. |
column_error |
number |
Код ошибки столбца, выдается в виде отрицательного числа. Ошибка будет устанавливать исключительную ситуацию, а column_error позволяет определить, какой из столбцов стал причиной конкретной ошибки. Если столбец был успешно прочитан, то column_error=0. |
actual_length |
number |
Если указан, то в данной переменной будет находится исходный размер столбца (размер столбца перед его считыванием). Это удобно в случае, когда размер переменной недостаточен и значение усекается (это также приводит к ошибке). |
В нижеследующем примере создается процедура, определяющая имена и фамилии сотрудников по заданной для данной процедуры должности сотрудника:
create or replace procedure DynamicQuery (p_position in staff.position %type) is
v_cursor_id integer;
v_select_stmt varchar2(500);
v_first_name staff.fname %type;
v_last_name staff.lname %type;
v_dummy integer;
begin
v_cursor_id := DBMS_SQL.OPEN_CURSOR;
v_select_stmt := ‘select lname, fname
from staff
where position = :pos
order by lname’;
DBMS_SQL.PARSE (v_cursor_id, v_select_stmt, DBMS_SQL.NATIVE);
DBMS_SQL.BIND_VARIABLE (v_cursor_id, ‘:pos’, p_position);
DBMS_SQL.DEFINE_COLUMN (v_cursor_id, 1, v_last_name, 25);
DBMS_SQL.DEFINE_COLUMN (v_cursor_id, 2, v_first_name, 25);
v_dummy := DBMS_SQL.EXECUTE (v_cursor_id);
loop
if DBMS_SQL.FETCH_ROWS (v_cursor_id)=0 then
exit;
end if;
DBMS_SQL.COLUMN_VALUE (v_cursor_id, 1, v_last_name);
DBMS_SQL.COLUMN_VALUE (v_cursor_id, 2, v_first_name);
insert into temp_table (name_col)
values (v_last_name || ’ ’ || v_first_name);
end loop;
DBMS_SQL.CLOSE_CURSOR (v_cursor_id);
commit;
exception
when others then
--ЗАКРОЕМ КУРСОР, А ЗАТЕМ ПОВТОРНО УСТАНОВИМ ОШИБКУ
DBMS_SQL.CLOSE_CURSOR (v_cursor_id);
raise;
end DynamicQuery;
