
- •3 Завдання до лабораторних робіт
- •3.1 Лабораторна робота № 1
- •1 Теоретические сведения
- •2 Ход работы
- •2.1 Создание базы данных
- •2.2 Регистрация базы данных
- •2.3 Подключение к базе данных
- •2.4 Удаление базы данных
- •2.5 Извлечение метаданных
- •2.6 Резервное копирование и восстановление
- •3 Задание
- •4 Отчет о выполнении работы
- •5 Контрольные вопросы
- •3.2 Лабораторна робота № 2
- •1 Теоретические сведения
- •1.1 Типы данных InterBase
- •2 Ход работы
- •3 Задание
- •4 Отчет о выполнении работы
- •5 Контрольные вопросы
- •3.3 Лабораторна робота № 3
- •1 Теоретические сведения
- •1.1 Таблицы (Tables)
- •1.2 Индексы
- •2 Ход работы
- •3 Задание
- •4 Отчет о выполнении работы
- •5 Контрольные вопросы
- •3.4 Лабораторная работа № 4
- •1 Теоретические сведения
- •1.2 Ограничение первичного ключа (Primary key)
- •1.2 Ограничения уникальности (Unique)
- •1.3 Ограничения внешнего ключа (Foreign keys)
- •1.4 Контрольные ограничения (Checks)
- •2 Ход работы
- •3 Задание
- •4 Отчет о выполнении работы
- •5 Контрольные вопросы
- •3.5 Лабораторная работа №5.
- •1 Теоретические сведения
- •1.1 Генераторы (Generators)
- •1.2 Бизнес-правила
- •1.3 Триггеры (Triggers)
- •2. Ход работы
- •3 Задание
- •4 Отчет о выполнении работы
- •5 Контрольные вопросы
- •3.6 Лабораторная работа №6
- •1 Теоретические сведения
- •1.1 Добавление новых данных
- •1.2 Удаление существующих данных
- •1.3 Обновление существующих данных
- •2. Ход работы
- •3. Задание
- •4. Отчет о выполнении работы
- •5. Контрольные вопросы
- •3.7 Лабораторная работа №7
- •1 Теоретические сведения
- •2. Ход работы
- •3. Задание
- •4. Отчет о выполнении работы
- •5. Контрольные вопросы
- •3.8 Лабораторная работа №8
- •1 Теоретические сведения
- •1.1 Представления (Views)
- •1.2 Модифицируемые представления
- •2 Ход работы
- •3 Задание
- •4 Отчет о выполнении работы
- •5 Контрольные вопросы
- •3.9 Лабораторная работа №9
- •1 Теоретические сведения
- •1.1 Хранимые процедуры (Procedures)
- •1.2 Виды хранимых процедур в InterBase
- •2 Ход работы
- •3 Задание
- •4. Отчет о выполнении работы
- •5. Контрольные вопросы
- •3.10 Лабораторная работа №10
- •1 Теоретические сведения
- •1.1 Функции пользователя (udFs)
1 Теоретические сведения
1.1 Функции пользователя (udFs)
Функциями пользователя (user defined functions) называются функции для выполнения операций, которые непосредственно не поддерживаются InterBase. Для сервера InterBase на платформе Windows функции пользователя располагаются внутри DLL-библиотек, созданных на языках C, C++, Pascal или других языках высокого уровня. К функциям пользователя можно обра-щаться из операторов SELECT, хранимых процедур и триггеров.
Процесс создание функции пользователя состоит из трех шагов:
1. Написание функции на одном из языков, таких как C или Delphi.
2. Создание динамической библиотеки, содержащей функцию и размещение ее в папке "С:\Program Files\Firebird 1.5\UDF\" на сервере.
3. Объявление функции пользователя в базе данных.
10.4.2. Создание динамической библиотеки с UDF
Ниже приведен пример библиотеки и модуля с тремя UDF:
// файл LibUDF.dpr с текстом библиотеки для Delphi 7: library LibUDF; uses ExtFunct in 'ExtFunct.pas'; exports IsDate index 1 name 'ISDATE', IBDateToStr index 2 name 'IBDATETOSTR', RoundFloat index 3 name 'ROUNDFLOAT'; end. 72
// файл ExtFunct.pas с текстом модуля для Delphi 7: unit ExtFunct; interface uses SysUtils; type PIBDateTime = ^TIBDateTime; TIBDateTime = record Date: Integer; Time: Integer; end; function IsDate(var InputDate: TIBDateTime): PIBDateTime; cdecl; function IBDateToStr(var InputDate: TIBDateTime): PChar; cdecl; function RoundFloat(var Value: Double; var Digits: Integer): Double; cdecl; procedure isc_decode_date(IBDateTime: PIBDateTime; P: Pointer); stdcall; implementation procedure isc_decode_date; external 'gds32.dll' name 'isc_decode_date'; var OutDate: TIBDateTime; function IsDate(var InputDate: TIBDateTime): PIBDateTime; cdecl; begin // первые 4 байта в InputDate - дата, // последние 4 байта в InputDate - время; // достаточно обнулить данные о времени чтобы // получить только дату. with OutDate do begin Date := InputDate.Date; Time := 0; end; Result := @OutDate; end;
73
type PCTimeStructure = ^TCTimeStructure; TCTimeStructure = record tm_sec : integer; // Seconds tm_min : integer; // Minutes tm_hour : integer; // Hour (0--23) tm_mday : integer; // Day of month (1--31) tm_mon : integer; // Month (0--11) tm_year : integer; // Year = "calendar year"-1900 tm_wday : integer; // Weekday (0--6) Sunday = 0) tm_yday : integer; // Day of year (0--365) tm_isdst : integer; end; var DateStr: string[11] = #0#0#0#0#0#0#0#0#0#0#0; function IBDateToStr(var InputDate: TIBDateTime): PChar; cdecl; var B: TCTimeStructure; D, M, Y, I: Integer; begin // преобразует дату из формата InterBase. isc_decode_date(@InputDate, @B); D := B.tm_mday; M := B.tm_mon + 1; Y := B.tm_year + 1900; DateStr := Format('%2d-%2d-%4d', [D, M, Y]); repeat I := Pos(' ', DateStr); if I > 0 then DateStr[I] := '0'; until I = 0; Result := @DateStr[1]; end; function RoundFloat(var Value: Double; var Digits: Integer): Double; cdecl; var F: Double; begin F := Frac(Value); case Digits of
74
1: F := Round(F*10.0)/10.0; 2: F := Round(F*100.0)/100.0; 3: F := Round(F*1000.0)/1000.0; else F := 0; end; Result := Int(Value) + F; end; end.
Еще один пример создания библиотеки с помощью Delphi с одной функцией пользователя:
T// Файл 'TestUDF.dpr'T для Delphi 7T: library TestUDF; // функция определения длины текста в строковых полях // типов CHAR(n) и VARCHAR(n): function LengthCharField(C: PChar): Integer; cdecl; begin // ищем нулевой символ, который является завершителем // строки: Result := 0; while (C[Result] <> #0) do Inc(Result); // Если бы эта функция использовалась бы только для // полей типа VARCHAR, то больше ничего делать не // надо было бы. // Если поле имеет тип CHAR, то оно всегда // дополняется до максимальной длины пробелами, // поэтому их надо учесть: Dec(Result); while (Result >= 0) and (C[Result] = ' ') do Dec(Result); Inc(Result); end; exports LengthCharField name 'LENGTH_CHAR_FIELD'; end.
Чтобы получить файл с DLL-библиотекой, содержащей UDF, можно, например, ввести исходный текст библиотеки с помощью любого редактора в
75
файл 'TestUDF.dpr' и откомпилировать его с помощью утилиты командной строки 'dcc32.exe', введя в командной строке следующую команду:
C:\Рабочая папка>dcc32 TestUDF.dpr
В результате этой команды будет создан файл 'TestUDF.DLL', который перед использованием необходимо поместить в специальную папку 'UDF', расположенную в папке с установленным сервером Firebird 1.5.
10.4.3. Объявление функций пользователя в базе данных
Синтаксис оператора объявления функции пользователя следующий:
DECLARE EXTERNAL FUNCTION name [datatype | CSTRING(int) [, datatype | CSTRING(int) ...]] RETURNS {datatype [BY VALUE] | CSTRING(int)} [FREE_IT] ENTRY_POINT 'entryname' MODULE_NAME 'modulename';
Параметры, входящие в этот оператор, пояснены в табл. 5.
Таблица 5
Описание параметров оператора описания UDF
Ниже приведены примеры объявления в базе данных созданных выше функций пользователя.
Параметр |
Описание |
name |
Имя функции внутри базы данных. Оно не обязательно должно совпадать с названием функции в DLL |
datatype |
Определяет тип параметров. Все параметры всегда передаются по ссылке. значение функ-ции (результат) может возвращаться по зна-чению |
CSTRING |
Используется для строковых параметров. В скобках необходимо указать максимальную длину строки. Если строка является результа-том функции, она всегда передается по ссыл-ке, т.е. возвращается адрес строки (указатель) |
'entryname' |
Строка с названиемTP‡‡PT функции в DLL, кото-рую мы объявляем как пользовательскую функцию |
'modulename' |
Строка с названием файла DLL, в котором находится функция |
‡‡ Параметры entryname и modulename чувствительны к регистру 76
DECLARE EXTERNAL FUNCTION ISDATE DATE RETURNS DATE ENTRY_POINT 'ISDATE' MODULE_NAME 'LIBUDF'; DECLARE EXTERNAL FUNCTION IBDATETOSTR DATE RETURNS CSTRING(11) ENTRY_POINT 'IBDATETOSTR' MODULE_NAME 'LIBUDF'; DECLARE EXTERNAL FUNCTION ROUNDFLOAT DOUBLE PRECISION, INTEGER RETURNS DOUBLE PRECISION BY VALUE ENTRY_POINT 'ROUNDFLOAT' MODULE_NAME 'LIBUDF'; -- функция определение длины строкового поля с -- отбрасыванием конечных пробелов: DECLARE EXTERNAL FUNCTION STRING_LENGTH CSTRING(100) -- в функцию передается указатель на -- строку, заканчивающуюся нулевым -- символом (#0) и длина здесь должна -- быть не меньше, чем длина поля CHAR -- или VARCHAR RETURNS INTEGER BY VALUE –- возврат по значению ENTRY_POINT 'LENGTH_CHAR_FIELD' MODULE_NAME 'EducatorUDF';
10.4.4. Использование UDF в базе данных
Объявленную в базе данных функцию пользователя можно использо-вать при создании доменов и таблиц в вычислимых полях, значениях по умолчанию и контрольных ограничениях. Их можно использовать в операто-рах изменения данных, триггерах, хранимых процедурах и просто в запросах.
Приведем пример запроса с созданными и объявленными выше функ-циями пользователя:
-- это запрос для базы данных Employee.fdb: SELECT SALARY, HIRE_DATE, ROUNDFLOAT(SALARY, 2), IBDateToStr(HIRE_DATE), IsDate(HIRE_DATE), CAST(SALARY AS INTEGER) FROM EMPLOYEE;
77
10.5. Задание
Лабораторную работу №10 следует выполнять в следующем порядке:
1. Создать аналогично предыдущим лабораторным работам рабочую папку и назвать ее "ЛР10".
2. Разработать для своей базы данных не менее трех функций пользователя.
3. Создать любым текстовым редактором файл, содержащий текст на языке Pascal с этими функциями. Назвать этот файл таким же именем, как базу данных. Дать ему расширение '.dpr'.
4. Откомпилировать его либо с помощью Delphi 7.0, либо с помощью ком-пилятора командной строки 'dcc32.exe'.
5. Поместить исходный файл проекта и откомпилированную библиотеку в рабочую папку "ЛР10" на сервере для копирования в папку 'UDF'.
6. Скопировать в эту папку файл сценария, созданный при выполнении пре-дыдущей лабораторной работы.
7. Открыть в приложении "IB Expert" этот сценарий.
8. Исправить текст комментариев и сделать, чтобы база данных теперь соз-давалась в папке "ЛР10".
9. Добавить в сценарий операторы описания разработанных функций поль-зователя. Для каждой функции пользователя должны присутствовать комментарии, поясняющие ее назначение.
10. Выполнить сценарий и сохранить его в папке "ЛР10".
11. Зарегистрировать созданную базу данных в программе "IB Expert" и под-ключиться к ней.
12. Выполнить в окне "SQL Editor" по одному запросу с каждой созданной функцией пользователя. Описать результаты этих запросов в отчете.
13. Создать в папке "ЛР10" резервную копию базы данных.
14. Создать и сохранить в папке "ЛР10" файл с отчетом о выполнении лабо-раторной работы, который должен называться "Отчет.doc".
10.6. Ход работы
Для создания файла проекта Delphi с исходным текстом библиотеки можно использовать либо среду программирования Delphi 7.0, либо любой текстовый редактор. Процесс получения откомпилированной библиотеки (файла с расширением '*.DLL') описан в разделе "Создание динамической библиотеки с UDF".
После помещения команд объявления функций пользователя в сцена-рий, его надо выполнить с помощью программы "IB Expert" аналогично пре-дыдущим лабораторным работам.78
10.7. Отчет о выполнении работы
Отчет о выполнении лабораторной работы №10 необходимо оформить на листах формата A4. Отчет должен содержать описание и результаты рабо-ты, представляемые в следующей последовательности:
1. Описание разработанных для своей базы данных функций пользователя.
2. Распечатка исходного текста проекта с функциями пользователя. Обяза-тельно должны присутствовать комментарии ко всему проекту со сведе-ниями о назначении файла и его авторе, а также комментарии к создан-ным функциям пользователя.
3. Текст операторов объявления UDF в базе данных.
4. Операторы, использующие созданные и объявленные в базе данных функции пользователя.
5. Примеры запросов с использованием разработанных функций и описание результата их выполнения.
6. Перечень файлов, полученных при выполнении лабораторной работы с указанием их имен, места расположения, даты изменения и размеров (сценарий, база данных, резервная копия базы данных, исходный текст проекта с функциями пользователя, откомпилированная библиотека с функциями пользователя, файл с отчетом).
10.8. Контрольные вопросы
1. Что такое функция пользователя?
2. Как расшифровывается UDF?
3. Как расшифровывается DLL?
4. Где должна располагаться библиотека, чтобы ее могла использовать СУБД Firebird 1.5?
5. Что означают в исходных текстах на Pascal: cdecl, stdcall, exports, external, Result, PChar?
6. Какие существуют способы передачи параметров в функцию?
7. Какой способ передачи параметров используется для UDF в InterBase?