Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LINTER от 04.02.15

.pdf
Скачиваний:
47
Добавлен:
21.05.2015
Размер:
2.16 Mб
Скачать

 

Практическое занятие 3. Загрузка и выгрузка данных

21

 

 

 

Задача 3. Выгрузить данные таблицы T1.

1.Создадим в рабочей директории директорию dbstore_tables;

2.Зайдем в директорию, содержащую dbstore;

3.Запустим процесс экспорта данных командой:

./dbstore –u SYSTEM/MANAGER –l T1 –f /home/linter/prac3/dbstore_tables/t1.lod

Задача 4. Выгрузить все объекты пользователя SYSTEM.

1.Создадим в рабочей директории директорию dbstore_systables;

2.Зайдем в директорию, содержащую dbstore;

3.Запустим процесс экспорта данных командой:

./dbstore –u SYSTEM/MANAGER –w SYSTEM –d /home/linter/prac3/dbstore_systables

Задача 5. (студенты выполняют самостоятельно) Выгрузить все представления пользователя SYSTEM в формате XML.

3.3. Импорт данных

Если база данных восстанавливается по схеме при помощи утилиты inl, то для импорта данных из файлов форматов TXT(LOD) и XML существует специализированная утилита loarel. Она предоставляет интерфейс командной строки и существует на всех программно-аппаратных платформах, поддерживаемых СУБД ЛИНТЕР.

Общий формат запуска утилиты:

LOAREL [-u NAME/PASSWORD] [-d DIRNAME] [-n NODE]

[-t [TABLENAME[,...]]]

[-x] [-version] [-?] [-end] [<прочие ключи>]

Полное описание ключей loarel можно найти в разделе «Импорт данных» пользовательской документации по СУБД ЛИНТЕР.

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

Задача 1. Создать и загрузить таблицу ERRORS из каталога dict дистрибутива СУБД ЛИНТЕР.

1.Предполагаем, что база только что создана и запущено ядро;

2.Перейдем в каталог bin дистрибутива и подадим команду на создание таблицы при помощи утилиты inl:

./inl –u SYSTEM/MANAGER –f ../dict/cerrors.sql

3. Подадим команду на загрузку данных в таблицу:

./loarel –u SYSTEM/MANAGER –t ERRORS –f ../dict/errors.lod

Задача 2. Загрузить данные таблицы T1.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

22

Практическое занятие 3. Загрузка и выгрузка данных

 

 

 

1.Предполагаем, в файле /home/linter/prac3/dbstore_tables/t1.lod находится информация, которую следует импортировать в таблицу T1;

2.Перейдем в каталог bin дистрибутива и подадим команду на удаление данных из таблицы при помощи утилиты inl:

./inl –u SYSTEM/MANAGER

SQL>delete from T1;

SQL>select * from T1;(проверим, что в таблице записей нет)

3. Запустим процесс импорта данных командой:

./loarel –u SYSTEM/MANAGER –t T1 –f /home/linter/prac3/dbstore_tables/t1.lod

4. Проверим, что данные были добавлены:

./inl –u SYSTEM/MANAGER

SQL>select * from T1;

Задача 3. Создать таблицу T1 и загрузить ее данные из файла формата XML.

1.Предполагаем, в файле /home/linter/prac3/dbstore_xml/SYSTEM.lod/T1.xml

находится описание таблицы T1 и ее данных;

2.Перейдем в каталог bin дистрибутива и подадим команду на удаление данных из таблицы при помощи утилиты inl:

./inl –u SYSTEM/MANAGER

SQL>drop table T1;

3. Запустим процесс импорта данных командой:

./loarel –u SYSTEM/MANAGER –f /home/linter/prac3/dbstore_xml/SYSTEM.lod/T1.xml –x

(указанная команда привела к падению loarel на Linux x86_64, на Windows падение не воспроизводится)

При этом будет создана таблица и будут импортированы данные.

Задача 4. (студенты выполняют самостоятельно) Создать три таблицы,

описывающие взаимосвязь между автомобилями и их владельцами (T_AUTO, T_PERSON, T_LINK), с учетом хранения промежутков времени владения человеком данной машиной. Заполнить их данными. Провести экспорт в текстовые файлы, поля которых разделены ‘#’.

Импортировать данные в другие таблицы (T1_AUTO, T1_PERSON, T1_LINK).

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

 

Практическое занятие 3. Загрузка и выгрузка данных

23

 

 

 

3.4. Импорт данных из формата DBF

Помимо широкого спектра утилит администрирования, которые «умеют» загружать данные в таблицы из DBF-формата, существует утилита dbf2lin, запускаемая из командной строки.

Полный формат вызова утилиты таков:

dbf2lin -f

имя_файла_dbf

[-u

имя_пользователя/пароль]

[-n

сервер] [-t имя_таблицы]

[-i

имя_файла_входных_параметров]

[-o

имя_файла_выходных_параметров]

[-b

тип_данных_атрибута_blob]

[-s номер_уровня_загрузки]

[-l] [-p] [-e] [-h] [-version]

[-k тип кодировки]

[-2

имя_файла_перенаправления_вывода]

[-c

количество записей в одной транзакции]

[-d

имя_blob_файла]

Задача 5. Создать таблицу AUTO и импортировать в нее данные из файла

/home/linter/samples/db/dbf/auto.dbf

1.Создадим таблицу AUTO (предполагаем, что СУБД ЛИНТЕР установлена в каталог /home/linter):

inl –u SYSTEM/MANAGER –f /home/linter/samples/db/sql/auto/cauto.sql;

2. Запустим процесс импорта:

dbf2lin –u SYSTEM/MANAGER –t AUTO –f /home/linter/samples/db/dbf/auto.dbf

Задача 6. (студенты выполняют самостоятельно) Импортировать данные из файла /home/linter/samples/db/dbf/person.dbf без предварительного создания таблицы.

3.5. Импорт и экспорт данных при помощи ldba

Как было показано в таблице (см. «Обзор средств для экспорта-импорта данных»), многие утилиты администрирования поддерживают импорт и экспорт данных.

В утилите ldba существует специальное подменю Файл, в котором представлены пункты для импорта и экспорта данных.

Задача 7. Импортировать данные из файла:

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

24

Практическое занятие 3. Загрузка и выгрузка данных

 

 

 

/home/linter/prac3/dbstore_xml/SYSTEM.lod/T1.xml. 1. Запустим ldba:

ldba –u SYSTEM/MANAGER

2.Через меню вызовем диалог Файл|Импорт из XML;

3.Выберем файл /home/linter/prac3/dbstore_xml/SYSTEM.lod/T1.xml;

4.Согласимся с конвертированием в новую таблицу;

5.Введем имя новой таблицы T1_1;

6.В появившемся диалоге выберем кнопку Выполнить.

Задача 8. (студенты выполняют самостоятельно) Создать таблицу

AUTO_PLANTS со столбцами ID типа integer, автоинкремент, первичный ключ; и NAME типа char(50), уникальное. Импортировать данные из файла /home/linter/samples/db/dbf/auto.dbf,

занося в столбец NAME данные из столбца MAKE.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

25

Практическое занятие 4 Создание, исполнение и отладка хранимых процедур и триггеров

Практика 2 часа (Лекция 4)

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

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

При проектировании баз данных часть в качестве первичного ключа некоторой таблицы используется суррогатный ключ – уникальное числовое значение. Для генерации значений такого ключа удобно использовать механизм последовательностей (sequence). Однако, в СУБД ЛИНТЕР версий младше 5.9 последовательности не поддерживаются. Другим удобным и универсальным способом для генерации уникальных значений может быть использование хранимой процедуры. Хранимая процедура будет обращаться к специальной таблице (назовем ее SEQUENCES), чтобы определить очередное значение.

Таблицу SEQUENCES можно создать следующим запросом:

create table SEQUENCES(

TAB_NAME VARCHAR(64) primary key not null,

CUR_VALUE INT

not null

);

Здесь колонка TAB_NAME хранит имена таблиц, для которых генерируются уникальные значения, а колонка CUR_VALUE – текущее значение для генерации.

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

SQL-операторы на создание таблицы SEQUENCES и хранимой процедуры

GeneratePK содержатся в файле sp_seq.sql. Процедура создается таким запросом:

create procedure GeneratePK(in tabname char(64)) result int

for debug

declare

var v cursor(value int); //

code

execute direct "lock table SEQUENCES wait;"; //

execute direct "update SEQUENCES set CUR_VALUE = CUR_VALUE + 1 where TAB_NAME = '"+

tabname+"';"; //

if rowcount() > 0 then

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

Практическое занятие 4 26 Создание, исполнение и отладка хранимых процедур и триггеров

open v for direct "select CUR_VALUE from SEQUENCES where TAB_NAME = '"+

tabname+"';"; //

else

execute direct "insert into SEQUENCES values ('"+tabname+"',1);"; //

v.value := 1; //

endif

execute direct "unlock table SEQUENCES;"; //

commit; //

return v.value; //

end;

Перед созданием процедуры должна быть создана таблица процедур с использованием dict\systab.sql.

(замечание: мы использовали блокировку таблицы, чтобы оградить двух одновременно работающих пользователей от возможности модификации одних и тех же данных; надо иметь в виду, что работать это будет только в режиме обработки транзакций,

отличном от autocommit).

Обратите внимание, что в теле процедуры все операторы, завершающиеся точкой с запятой, содержат пустой комментарий в конце строки (символы //). Эта простая техника позволяет выполнять такой запрос из утилиты inl, которая считает точку с запятой в конце строки признаком окончания запроса.

Итак, простым способом создания хранимой процедуры является подача соответствующего запроса; например, из утилиты inl.

Выполняем команды:

 

перейти в директорию, содержащую файл sp_seq.sql;

 

запускаем inl и соединяемся с сервером БД;

 

исполняем файл: _sp_seq.

Теперь процедура создана. Запустить ее можем тут же, из inl, например:

SQL>

Return value = 1

SQL> execute generatepk(‘TEST’);

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Практическое занятие 4

 

Создание, исполнение и отладка хранимых процедур и триггеров

27

Return value = 2

Мы создали процедуру с опцией FOR DEBUG, что позволяет нам отлаживать ее исполнение.

Для отладки необходимо запустить утилиту spman

(ЛИНТЕР-ВС: в дистрибутиве ЛИНТЕР-ВС утилита для отладки хранимых процедур

итриггеров называется spdebug; отличается она тем, что в ней нет возможности создавать

имодифицировать процедуры).

По команде «Открыть процедуру…» в меню «Файл» выбираем нужную процедуру. Ее код показывается в отдельном окне. Теперь можно запустить ее из-под отладчика (команда «Отладчик/Пуск» или клавиша F9). На запрос входных параметров укажем значение ‘TEST’ (апострофы обязательны для символьных констант). В результате процедура запускается и останавливается для отладки на первой строке (она подсвечивается). Можно наблюдать значения локальных переменных.

В меню «Отладчик» перечислены команды для отладки процедур и соответствующие горячие клавиши. Так, можно пройти процедуру по шагам, исполнять процедуру до точек останова, до конца, или принудительно завершить процедуру, если наc не устраивает текущих ход ее работы. Кроме локальных переменных, можно просматривать значения любых приложений и стека вызова (если процедура вызвана из другой процедуры).

Выполняем команды:

проходим процедуру по шагам до конца (в окне «Сообщения» отображаются результаты работы);

заново запускаем процедуру, но в качестве параметра передаем ‘TEST1’; проходим процедуру по шагам (видно, что исполнение теперь идет по другой ветке: вставляется новая запись в таблицу SEQUENCES).

Отлаживать можно также процедуру, запущенную не только из-под отладчика, но и любой другой задачей. Для этого надо включить ожидание запуска процедуры: открыть процедуру в spman, открыть отладочную сессию (если она еще не открыта), и активизировать ожидание (команда «Ждать процедуру/триггер»). Теперь можно в другой сессии запустить inl и подать запрос типа execute. Процедура попадет в режим отладки, а inl будет ждать ее окончательного завершения.

4.2. Модификация процедуры, синтаксические ошибки

Допустим теперь, что мы хотим, чтобы была возможность задать приращение для генерируемых нашей процедурой значений. Для этого надо добавить еще один входной параметр (со значением по умолчанию 1), и использовать его в теле процедуры.

Чтобы модифицировать процедуру, надо выполнить запрос alter procedure с полным новым телом процедуры. Можно сделать соответствующий sql-файл и использовать inl, но еще удобнее воспользоваться spman.

Просто отредактируем заголовок процедуры в ее окне: после

tabname char(64)

всписке параметров добавим

;in change int default 1

Теперь надо модифицировать запрос в строке 7

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

Практическое занятие 4 28 Создание, исполнение и отладка хранимых процедур и триггеров

execute direct "update SEQUENCES set CUR_VALUE = CUR_VALUE + 1 where TAB_NAME = '"

пытаемся заменить на

execute direct "update SEQUENCES set CUR_VALUE = CUR_VALUE + “+change+” where TAB_NAME = '"

Теперь для сохранения процедуры просто можно выбрать команду обработки в меню «Файл» или нажать клавишу <F2>. spman автоматически генерирует запрос alter procedure. Однако трансляция процедуры на этот раз проходит неудачно, и мы получаем окно со списком ошибок. Нажав <Enter> на тексте сообщения об ошибке, можно попасть в то место, где была ошибка.

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

execute direct "update SEQUENCES set CUR_VALUE = CUR_VALUE + “+itoa(change)+” where TAB_NAME = '"

Теперь процедура транслируется удачно, о чем свидетельствует исчезнувшее окно с ошибками. Заметим, что при подаче запроса из inl мы не получим полной расшифровки ошибок, только общий код завершения 7200 – ошибка трансляции хранимой процедуры.

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

4.3. Обработка ошибок, исключения

Наша процедура будет некорректно работать, если в качестве значения параметра change передать значение, меньшее единицы, или NULL. Мы можем вставить соответствующую проверку в начало тела процедуры:

if change = NULL or change < 1 then

signal INVPARAM; endif

Оператор signal вызывает исключение с именем INVPARAM. Это исключение необходимо описать в секции деклараций процедуры, например перед ключевым словом code:

exception INVPARAM for BADPARAM;

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

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Практическое занятие 4

 

Создание, исполнение и отладка хранимых процедур и триггеров

29

Попробуем запустить процедуру и указать неправильное значение (например, 0) в качестве параметра change. Отладчик всегда останавливается в строке, в которой произошло исключение.

Если мы запустим процедуру с неверными параметрами из inl, то тоже получим информацию об исключении. Запрос execute, завершившийся с исключением, всегда имеет код возврата 7201.

Чтобы обработать исключение внутри процедуры, необходимо использовать блок EXCEPTIONS, как было рассмотрено в лекции.

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

(Замечание: конечно, мы могли бы в запросах явно написать SYSTEM.SEQUENCES; это более верно, но тем не менее, может возникнуть ошибка нарушения прав доступа; чтобы процедура реально работала для нескольких пользователей, обычно удобно создать общие (PUBLIC) синонимы на используемые таблицы, или же использовать полное имя таблицы, и в любом случае надо назначить необходимые права

grant execute on GENERATEPK to PUBLIC;).

Если мы подадим запрос на выполнение SYSTEM.GENERATEPK из-под другого пользователя (не SYSTEM), то увидим, что процедура всегда возвращает 1. Чтобы разобраться, в чем дело, можно запустить ожидание процедуры и прийти в режим ее отладки. В отладчике мы видим, что при попытке исполнения запросов происходит исключение 2202 (нет такой таблицы), но процедура продолжает исполняться. Это происходит из-за того, что исключение некритичное, и при отсутствии обработки оно просто игнорируется. Значит, нам необходимо обработать это исключение.

В секции определений объявим исключение:

exception NOTAB for 2202;

А в конец процедуры (перед end) добавим блок обработки исключения:

exceptions

when NOTAB then resignal;

Оператор resignal завершает процедуру и передает состояние исключения на уровень выше.

Теперь наша процедура корректно реагирует на ошибку 2202 исполнения запросов.

4.4. Упражнение: создание еще одной процедуры

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

Это логику удобно вынести в отдельную хранимую процедуру, назовем ее DropTabWithSequence. Процедура должна сначала удалить таблицу, а затем, в случае успеха, удалить соответствующую запись из таблицы SEQUENCES.

spman предоставляет специальный интерфейс для создания процедур: по сути он просто подготовит запрос create procedure для Вас. Используйте пункт «Новая процедура» меню «Файл». Предупреждение: в диалоге создания процедуры регистр символов имени

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

Практическое занятие 4 30 Создание, исполнение и отладка хранимых процедур и триггеров

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

В результате получаем окно с шаблоном текста процедуры. Надо дописать входной параметр (имя таблицы) и тело процедуры (указание: для проверки любого ненормального кода завершения запроса drop table удобно использовать стандартную функцию errcode).

Примечание: Студенты пытаются написать процедуру сами…

(процедура должна иметь примерно такой вид:

create procedure "DROPTABWITHSEQUENCE"(in tabname char(64)) for debug

code

execute direct "drop table "+tabname+";"; if errcode() = 0 then

execute direct "delete from SEQUENCES where tab_name='"+tabname+"';";

commit; endif

end;

)

4.5. Создание триггера

Рассмотрим пример триггера, который использует созданную нами ранее хранимую процедуру для генерации значений первичного ключа при вставке записей в некоторую таблицу OBJECT:

create table object(id int primary key, value varchar(64));

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

create trigger INS_OBJECT before insert on object

for each row execute for debug code

call GeneratePk("OBJECT") into new.id; // end;

Соответствующие SQL-операторы содержатся в файле trig_obj.sql. Его можно исполнить обычным способом, через inl. Теперь попробуйте добавить несколько записей в таблицу object. Потом подать SELECT из этой таблицы – мы видим сгенерированные значения колонки ID.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]