- •Глава 2 Базовые понятия реляционной модели данных 21
- •Глава 3. Целостность реляционных данных 28
- •Глава 4. Реляционная алгебра 39
- •Глава 6. Нормальные формы отношений 57
- •Глава 7 Нормальные формы более высоких порядков 74
- •Глава 8. Элементы модели «сущность-связь» 83
- •Глава 5. Элементы языка sql 110
- •Ранние подходы к организации бд. Системы, основанные на инвертированных списках, иерархические и сетевые субд. Примеры. Сильные места и недостатки ранних систем
- •Основные особенности систем, основанных на инвертированных списках
- •Структуры данных
- •Манипулирование данными
- •Ограничения целостности
- •Иерархические системы
- •Иерархические структуры данных
- •Манипулирование данными
- •Ограничения целостности
- •Сетевые системы
- •Сетевые структуры данных
- •Манипулирование данными
- •Ограничения целостности
- •Достоинства и недостатки
- •Элементы теории множеств Множества
- •Операции над множествами
- •Декартово произведение множеств
- •Отношение
- •Примеры отношений Бинарные отношения (отношения степени 2)
- •Отношение эквивалентности
- •Отношения порядка
- •Функциональное отношение
- •Еще пример бинарного отношения
- •Транзитивное замыкание отношений
- •Глава 2 Базовые понятия реляционной модели данных Общая характеристика реляционной модели данных
- •Типы данных
- •Простые типы данных
- •Структурированные типы данных
- •Ссылочные типы данных
- •Типы данных, используемые в реляционной модели
- •Отношения, атрибуты, кортежи отношения Определения и примеры
- •Свойства отношений
- •Первая нормальная форма
- •Глава 3. Целостность реляционных данных
- •Null-значения
- •Трехзначная логика (3vl)
- •Потенциальные ключи
- •Целостность сущностей
- •Внешние ключи
- •Целостность внешних ключей
- •Замечания к правилам целостности сущностей и внешних ключей
- •Операции, могущие нарушить ссылочную целостность
- •Для родительского отношения
- •Для дочернего отношения
- •Стратегии поддержания ссылочной целостности
- •Применение стратегий поддержания ссылочной целостности
- •При обновлении кортежа в родительском отношении
- •При удалении кортежа в родительском отношении
- •При вставке кортежа в дочернее отношение
- •При обновлении кортежа в дочернем отношении
- •Глава 4. Реляционная алгебра Обзор реляционной алгебры
- •Замкнутость реляционной алгебры
- •Отношения, совместимые по типу
- •Оператор переименования атрибутов
- •Теоретико-множественные операторы Объединение
- •Пересечение
- •Вычитание
- •Декартово произведение
- •Специальные реляционные операторы Выборка (ограничение, селекция)
- •Проекция
- •Соединение
- •Общая операция соединения
- •Тэта-соединение
- •Экви-соединение
- •Естественное соединение
- •Деление
- •Примеры использования реляционных операторов
- •Невыразимость транзитивного замыкания реляционными операторами
- •Кросс-таблицы
- •Реляционное исчисление
- •Кортежные переменные и правильно построенные формулы
- •Целевые списки и выражения реляционного исчисления
- •Реляционное исчисление доменов
- •Глава 6. Нормальные формы отношений Этапы разработки базы данных
- •Критерии оценки качества логической модели данных
- •Адекватность базы данных предметной области
- •Легкость разработки и сопровождения базы данных
- •Скорость операций обновления данных (вставка, обновление, удаление)
- •Скорость операций выборки данных
- •Основной пример
- •1Нф (Первая Нормальная Форма)
- •Аномалии обновления
- •Аномалии вставки (insert)
- •Аномалии обновления (update)
- •Аномалии удаления (delete)
- •Функциональные зависимости
- •Определение функциональной зависимости
- •Функциональные зависимости отношений и математическое понятие функциональной зависимости
- •2Нф (Вторая Нормальная Форма)
- •Анализ декомпозированных отношений
- •Оставшиеся аномалии вставки (insert)
- •Оставшиеся аномалии обновления (update)
- •Оставшиеся аномалии удаления (delete)
- •3Нф (Третья Нормальная Форма)
- •Алгоритм нормализации (приведение к 3нф)
- •Анализ критериев для нормализованных и ненормализованных моделей данных Сравнение нормализованных и ненормализованных моделей
- •Oltp и olap-системы
- •Корректность процедуры нормализации – декомпозиция без потерь. Теорема Хеза
- •Глава 7 Нормальные формы более высоких порядков
- •Нфбк (Нормальная Форма Бойса-Кодда)
- •4Нф (Четвертая Нормальная Форма)
- •5Нф (Пятая Нормальная Форма)
- •Продолжение алгоритма нормализации (приведение к 5нф)
- •Глава 8. Элементы модели «сущность-связь»
- •Основные понятия er-диаграмм
- •Нормальные формы er-схем
- •Более сложные элементы er-модели
- •Получение реляционной схемы из er-схемы
- •Пример разработки простой er-модели
- •Концептуальные и физические er-модели
- •Внутренняя организация реляционных субд Cтруктуры внешней памяти, методы организации индексов
- •Хранение отношений
- •Индексы
- •Хэширование
- •Журнальная информация
- •Служебная информация
- •Управление транзакциями, сериализация транзакций
- •Транзакции и целостность баз данных
- •Изолированность пользователей
- •Сериализация транзакций
- •Методы сериализации транзакций
- •Синхронизационные захваты
- •Гранулированные синхронизационные захваты
- •Предикатные синхронизационные захваты
- •Тупики, распознавание и разрушение
- •Метод временных меток
- •Журнализация изменений бд
- •Журнализация и буферизация
- •Индивидуальный откат транзакции
- •Восстановление после мягкого сбоя
- •Физическая согласованность базы данных
- •Восстановление после жесткого сбоя
- •Глава 5. Элементы языка sql
- •Предварительные сведения о работе с sql сервером.
- •InterBase сервер
- •Выполнение в ibConsole
- •Р егистрация псевдонима (алиаса).
- •Пользователи.
- •С оздание модельных бд.
- •Сеанс sql
- •Структура учебных баз данных
- •Операторы sql
- •Операторы ddl (Data Definition Language) - операторы определения объектов базы данных
- •Операторы dml (Data Manipulation Language) - операторы манипулирования данными
- •Операторы dql (Data Query Language) – операторы запросов к данным
- •Операторы dcl (Data Control Language) - защиты и управления данными
- •Основные типы данных
- •Строки фиксированной длины
- •Строки переменной длины
- •Числовые значения
- •Десятичные значения
- •Десятичные значения с плавающей точкой
- •Значения даты и времени
- •Буквальные значения
- •Значения null
- •Значения типа boolean
- •Пользовательские типы данных
- •Типы данных InterBase
- •Управление объектами базы данных
- •Что такое объекты базы данных?
- •Что такое схема?
- •Поля и столбцы
- •Оператор create database
- •Синтаксис
- •Примеры
- •Оператор create table
- •Синтаксис
- •Примеры
- •Ключевое слово storage (в InterBase не действует!)
- •Соглашения о присвоении имен
- •Команда alter table
- •Синтаксис
- •Примеры
- •Модификация элементов таблицы
- •Добавление столбцов, требующих обязательного ввода данных
- •Пример:
- •Изменение столбцов
- •Создание таблицы на основе уже существующей
- •Удаление таблиц
- •Условия целостности
- •Ключевые поля
- •Требования уникальности
- •Внешние ключи
- •Атрибут not null
- •Использование условий проверки
- •Удаление условий
- •Определение представлений
- •Оператор create view (InterBase) Описание
- •Синтаксис
- •Примеры
- •Определение привилегий
- •Оператор grant (InterBase) Описание
- •Синтаксис
- •Примеры
- •Вопросы и ответы
- •Практикум
- •Примеры
- •Манипуляция данными
- •Обзор возможностей манипуляции данными
- •Заполнение таблиц новыми данными
- •Ввод данных в таблицу
- •Ввод данных в определенные столбцы таблицы
- •Ввод данных из другой таблицы
- •Ввод значений null
- •Обновление уже имеющихся данных
- •Обновление значений одного столбца
- •Обновление нескольких столбцов в одной или нескольких записях
- •Удаление данных из таблиц
- •Примеры использования операторов манипулирования данными
- •Знакомство с запросами
- •Что такое запрос?
- •Оператор select
- •Синтаксис оператора выборки данных (select)
- •Синтаксис оператора выборки
- •Синтаксис
- •Примеры
- •Ключевое слово select
- •Ключевое слово from
- •Использование условий для отбора данных
- •Сортировка вывода
- •Учет регистра символов
- •Примеры простых запросов
- •Подсчет записей в таблице
- •Получение данных из таблиц других пользователей
- •Псевдонимы столбцов
- •Упражнения
- •Операции в условиях для отбора данных
- •Что такое операции в sql?
- •Операции сравнения
- •Равенство
- •Неравенство
- •«Меньше» и «больше»
- •Примеры комбинирования операций сравнения
- •Логические операции
- •Использование операторов exists, any, all, и some Описание учебной базы данных
- •Операции конъюнкции и дизъюнкции
- •Отрицание условий с помощью операции отрицания
- •Неравенство
- •Деление
- •Комбинирование арифметических операций
- •Вопросы и ответы
- •Подведение итогов по данным запроса
- •Что такое итоговые функции?
- •Функция count
- •Функция sum
- •Функция avg
- •Функция max
- •Функция min
- •Описание
- •Синтаксис
- •Примеры
- •Описание
- •Примеры
- •Описание
- •Синтаксис
- •Примеры
- •Описание
- •Синтаксис
- •Примеры
- •Описание
- •Синтаксис
- •Примеры
- •Сортировка и группирование данных
- •Зачем группировать данные?
- •Ключевое слово group by
- •Группирование выбранных данных
- •Создание групп и использование итоговых функций
- •Представление имен столбцов числами
- •Ключевое слово having
- •Объединение таблиц в запросах
- •Отбор данных из нескольких таблиц
- •Типы связывания
- •Компоненты условия связывания
- •Связывание по равенству
- •Естественное связывание
- •Использование псевдонимов для имен таблиц
- •Связывание по неравенству
- •Внешнее связывание
- •Рекурсивное связывание
- •Связывание по нескольким ключам
- •Вопросы связывания
- •Использование связующей таблицы
- •Декартово произведение
- •Вопросы и ответы
- •Практикум
- •Упражнения
- •Использование подзапросов
- •Что такое подзапрос?
- •Подзапросы в операторе select
- •Подзапросы в операторе insert
- •Подзапросы в операторе update
- •Подзапросы в операторе delete
- •Подзапросы внутри подзапросов
- •Связанные подзапросы
- •Объединение запросов
- •Обычные и составные запросы
- •Зачем использовать составные запросы?
- •Команды построения сложных запросов
- •Команда union
- •Команда union all
- •Команда intersect
- •Команда except
- •Использование order by в составных запросах
- •Использование group by в составных запросах
- •Обеспечение правильности результатов
- •Примеры использования оператора select
- •Отбор данных из одной таблицы
- •Отбор данных из нескольких таблиц
- •Использование имен корреляции (алиасов, псевдонимов)
- •Использование агрегатных функций в запросах
- •Использование агрегатных функций с группировками
- •Использование подзапросов
- •Использование объединения, пересечения и разности
- •Синтаксис соединенных таблиц
- •Синтаксис условных выражений раздела where
- •Порядок выполнения оператора select
- •Стадия 1. Выполнение одиночного оператора select
- •Стадия 2. Выполнение операций union, except, intersect
- •Стадия 3. Упорядочение результата
- •Как на самом деле выполняется оператор select
- •Оператор соединения
- •Оператор пересечения
- •Оператор деления
- •Использование индексов для ускорения поиска данных
- •Что такое индекс?
- •Принцип работы индексов
- •Команда create index
- •Типы индексов
- •Простые индексы
- •Уникальные индексы
- •Составные индексы
- •Простые и составные индексы
- •Неявные индексы
- •Когда следует создавать индекс?
- •Когда не следует создавать индекс?
- •Удаление индексов
- •Повышение эффективности работы с базой данных
- •Что означает оптимизация операторов sql?
- •Оптимизация базы данных и оптимизация операторов sql
- •Форматирование операторов sql
- •Форматирование операторов для лучшего восприятия
- •Правильный порядок таблиц в выражении from
- •Правильный порядок условий связывания
- •Наиболее ограничительное условие
- •Полное сканирование таблиц
- •Когда и как избегать полного сканирования таблиц
- •Другие аспекты оптимизации
- •Использование like и знаков подстановки
- •Замена операций or выражением с ключевым словом in
- •Недостатки использования выражения с ключевым словом having
- •Долгие операции сортировки
- •Использование готовых процедур
- •Отмена использования индексов в больших пакетных операциях
- •Средства для анализа производительности
- •Создание и использование представлений и синонимов
- •Что такое представление?
- •Использование представлений для защиты данных
- •Использование представлений для управления выводом данных
- •Хранение представлений
- •Создание представлений
- •Создание представления для данных одной таблицы
- •Создание представления для данных нескольких таблиц
- •Создание представления на основе другого представления
- •Уровни зависимости представлений
- •Опция with check option
- •Опции cascaded и local
- •Синтаксис
- •Примеры
- •Обновление данных представления
- •Представления и выражение order by
- •Удаление представлений
- •Что такое синонимы? (InterBase не поддержвается)
- •Управление синонимами
- •Создание синонимов
- •Удаление синонимов
- •Триггеры и хранимые процедуры (InterBase) sql для триггеров и хранимых процедур в InterBase
- •Обработка исключений
- •Обработка ошибок sql
- •Обработка ошибок InterBase
- •Комментарий
- •Триггеры и их назначение
- •Синтаксис create trigger
- •Примеры
- •Дополнительные сведения по работе с генераторами
- •Хранимые процедуры и их назначение
- •Процедуры для работы с датой и временем
Процедуры для работы с датой и временем
EXTRACT() function
The EXTRACT() function extracts date and time information from databases.
EXTRACT() has the following syntax:
EXTRACT (part FROM value)
The value passed to the EXTRACT() expression must be a DATE, TIME, or TIMESTAMP datatype. Extracting a part that doesn’t exist in a datatype results in an error. For example, the following expression would fail:
EXTRACT (YEAR FROM aTime).
CAST() function
You can use the CAST() function in SELECT statements to translate between date/time datatypes and various character-based datatypes. It is not possible to cast a date/time datatype to or from BLOB, SMALLINT, INTEGER, FLOAT, DOUBLE PRECISION, NUMERIC, or DECIMAL datatypes.
Note that there are some differences from behavior in past versions of InterBase:
Casting DATE to string results in YYYY-MM-DD where” M”M is a two-digit month. If the result does not fit in the string variable a string truncation exception is raised. In earlier versions, this case results in DD-Mon- YYYY HH:mm:SS.hundreds where “Mon” was a 3-letter English month abbreviation. Inability to fit in the string variable resulted in a silent truncation.
First/last day of month
First day of month:
D - EXTRACT(DAY FROM D) + 1;
Last day of month:
LDM = D - EXTRACT(DAY FROM D) + 32;
LDM = LDM - EXTRACT(DAY FROM LDM);
or as single expression
D - EXTRACT(DAY FROM D) + 32 - EXTRACT(DAY FROM D - EXTRACT(DAY FROM D) + 32)
First day of next month:
FDNM = D - EXTRACT(DAY FROM D) + 32;
FDNM = FDNM - EXTRACT(DAY FROM FDNM) + 1;
or as single expression
D - EXTRACT(DAY FROM D) + 33 - EXTRACT(DAY FROM D - EXTRACT(DAY FROM D) + 32)
Процедуры для работы с датой и временем для InterBase6 (работоспособность проверена).
SET TERM # ;
CREATE PROCEDURE ReturnYear(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = EXTRACT(YEAR FROM ADate);
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE Return_Day(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = EXTRACT(DAY FROM ADate);
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE Return_Month(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = EXTRACT(MONTH FROM ADate);
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE EncodeDate(Year_n INTEGER, Month_n INTEGER, Day_n INTEGER)
RETURNS (Result DATE)
AS
BEGIN
Result = CAST((Day_n || '.' || Month_n || '.' || Year_n) AS DATE);
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE DecodeDate(ADate DATE)
RETURNS (Year_ INTEGER, Month_ INTEGER, Day_ INTEGER)
AS
BEGIN
EXECUTE PROCEDURE ReturnYear(ADate) RETURNING_VALUES Year_;
EXECUTE PROCEDURE Return_Month(ADate) RETURNING_VALUES Month_;
EXECUTE PROCEDURE Return_Day(ADate) RETURNING_VALUES Day_;
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE ElapsedDays(Date1 DATE, Date2 DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = Date2 - Date1;
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE DayOfWeek(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = EXTRACT(WEEKDAY FROM ADate);
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE Return_Time(ADate DATE)
RETURNS (RHour INTEGER, RMinute INTEGER)
AS
DECLARE VARIABLE RYear INTEGER;
DECLARE VARIABLE RMonth INTEGER;
DECLARE VARIABLE RDay INTEGER;
DECLARE VARIABLE WorkDate DATE;
DECLARE VARIABLE Percent DOUBLE PRECISION;
DECLARE VARIABLE WorkHour DOUBLE PRECISION;
BEGIN
EXECUTE PROCEDURE DecodeDate(ADate) RETURNING_VALUES(RYear, RMonth, RDay);
EXECUTE PROCEDURE EncodeDate(RYear, RMonth, RDay) RETURNING_VALUES(WorkDate);
Percent = ADate - WorkDate;
WorkHour = Percent *24;
RHour = WorkHour -0.5;
RMinute = (WorkHour - RHour) *60 -0.5;
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE DaysOfMonth(AYear INTEGER, AMonth INTEGER)
RETURNS (Result INTEGER)
AS
DECLARE VARIABLE WorkDate DATE;
BEGIN
Result = 31;
WHILE (Result > 28 AND WorkDate IS NULL) DO
BEGIN
EXECUTE PROCEDURE EncodeDate(AYear, AMonth, Result) RETURNING_VALUES(WorkDate);
WHEN ANY DO Result = Result - 1;
END
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE DayOfYear(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = EXTRACT(YEARDAY FROM ADate);
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE AddMonth(ADate DATE, AMonth INTEGER)
RETURNS (Result DATE)
AS
DECLARE VARIABLE RYear INTEGER;
DECLARE VARIABLE RMonth INTEGER;
DECLARE VARIABLE RDay INTEGER;
DECLARE VARIABLE Mod INTEGER;
DECLARE VARIABLE DaysOfMOnth INTEGER;
BEGIN
EXECUTE PROCEDURE DecodeDate(ADate) RETURNING_VALUES(RYear, RMonth, RDay);
IF(AMonth < 0) THEN
BEGIN
AMonth = AMonth * -1;
RYear = RYear - CAST(((AMonth - 1)/12) - 0.49 AS INTEGER) - 1;
AMonth = AMonth - 1;
EXECUTE PROCEDURE Modulus(AMonth, 12) RETURNING_VALUES(Mod);
AMonth = 12 - (Mod + 1);
RMonth = RMonth + AMonth;
END
ELSE
BEGIN
RYear = RYear + CAST(((AMonth - 1)/12) - 0.49 AS INTEGER);
AMonth = AMonth - 1;
EXECUTE PROCEDURE Modulus(AMonth, 12) RETURNING_VALUES(Mod);
RMonth = RMonth + Mod + 1;
END
IF(RMonth > 12) THEN
BEGIN
RYear = RYear + 1;
RMonth = RMonth - 12;
END
EXECUTE PROCEDURE DaysOfMonth(RYear, RMonth) RETURNING_VALUES (DaysOfMonth);
IF(RDay > DaysOfMonth) THEN RDay = DaysOfMonth;
EXECUTE PROCEDURE EncodeDate(RYear, RMonth, RDay) RETURNING_VALUES (Result);
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE DayOfWeekISO(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = EXTRACT(WEEKDAY FROM ADate - 1) + 1;
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE WeekOfYear(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = (EXTRACT(YEARDAY FROM ADate) - EXTRACT(WEEKDAY FROM ADate - 1) + 7) / 7;
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE YearWeek (D DATE)
RETURNS (WEEK_NO VARCHAR(8)) AS
DECLARE VARIABLE W INTEGER; /* week number */
DECLARE VARIABLE Y INTEGER; /* year the week belongs to */
BEGIN
W = (EXTRACT(YEARDAY FROM D) - EXTRACT(WEEKDAY FROM D-1) + 7) / 7;
Y = EXTRACT(YEAR FROM D);
IF (W=0) THEN BEGIN
Y = Y - 1;
D = D - EXTRACT(YEARDAY FROM D) - 1; /* last day of previous year; D is used as temporary variable here */
W = (EXTRACT(YEARDAY FROM D) - EXTRACT(WEEKDAY FROM D-1) + 7) / 7;
END
ELSE
IF (W=53 AND 4>EXTRACT(WEEKDAY FROM (D - EXTRACT(DAY FROM D) + 31))) THEN BEGIN
Y = Y + 1;
W = 1;
END
/* This is just formatting; you may prefer to make W and Y return parameters instead. */
IF (W<10) THEN
WEEK_NO = '0';
ELSE
WEEK_NO = '';
WEEK_NO = Y || '/' || WEEK_NO || W;
SUSPEND;
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE Is_LeapYear_IB5 (Y INTEGER) RETURNS (LY INTEGER) AS
DECLARE VARIABLE D DATE;
BEGIN
LY = 1;
D = CAST('29-FEB-' || Y AS DATE);
WHEN ANY DO LY = 0;
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE Is_LeapYear_d (D DATE) RETURNS (LY INTEGER) AS
BEGIN
IF ( 2 = EXTRACT(MONTH FROM (D - EXTRACT(YEARDAY FROM D) + 59)) ) THEN
LY = 1; /* leap year */
ELSE
LY = 0; /* normal year */
END
#
SET TERM ; #
SET TERM # ;
CREATE PROCEDURE Is_LeapYear (Y INTEGER) RETURNS (LY INTEGER) AS
BEGIN
IF ( 60 = EXTRACT(YEARDAY FROM CAST(Y || '-3-1' AS TIMESTAMP)) ) THEN
LY = 1; /* leap year */
ELSE
LY = 0; /* normal year */
END
#
SET TERM ; #
/*------------------------------------------------------------
Date and time stored procedures
--------------------------------------------------------------
This script file contains the following procedures:
Year - Returns the year part of a date.
Month - Returns the month part of a date.
Day - Returns the day part of a date.
EncodeDate - Creates a date from its parts.
DecodeDate - Extracts a date to its parts.
ElapsedDays - Returns the number of days between two days.
Modulus - Returns the modulus of a division.
DayOfWeek - Returns the number of the day of week.
Time - Returns the hour and minute of a date.
DaysOfMonth - Returns the number of days in a given month.
DayOfYear - Returns the number of the day in the given year.
AddMonth - Adds given number of months to a date.
--------------------------------------------------------------
*/
SET TERM # ;
/* The calculation is based on the following mathematical algorithm:
ElapsedDays = ElapsedYears*365 +(ElapsedYears/4) +(ElapsedYears/100) +(ElapsedYears/400)
ElapsedDays = ElapsedYears*365 +(ElapsedYears*97/400)
ElapsedDays = ElapsedYears*146097/400
ElapsedDays*400/146097 = ElapsedYears
*/
CREATE PROCEDURE Year(ADate DATE)
RETURNS (Result INTEGER)
AS
DECLARE VARIABLE ElapsedDays INTEGER;
DECLARE VARIABLE ElapsedYears INTEGER;
BEGIN
/* Lets go to the begin of the year */
WHILE(CAST(ADate AS VARCHAR(5)) <> "1-JAN") DO
ADate = ADate -1;
ElapsedDays = ADate -"1.1.1901";
Result = (ElapsedDays *400 /146097)+1901;
END
#
CREATE PROCEDURE Day(ADate DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = CAST(CAST(ADate AS VARCHAR(2)) AS INTEGER);
WHEN ANY DO Result = CAST(CAST(ADate AS VARCHAR(1)) AS INTEGER);
END
#
CREATE PROCEDURE Month(ADate DATE)
RETURNS (Result INTEGER)
AS
DECLARE VARIABLE WorkDate DATE;
DECLARE VARIABLE WorkDay INTEGER;
BEGIN
WorkDate = ADate;
Result = 1;
WHILE(CAST(WorkDate AS VARCHAR(5)) <> "1-JAN") DO
BEGIN
EXECUTE PROCEDURE Day(WorkDate) RETURNING_VALUES WorkDay;
IF(WorkDay = 1) THEN Result = Result+1;
WorkDate = WorkDate-1;
END
END
#
CREATE PROCEDURE EncodeDate(Year INTEGER, Month INTEGER, Day INTEGER)
RETURNS (Result DATE)
AS
BEGIN
Result = Day || "." || Month || "." || Year;
END
#
CREATE PROCEDURE DecodeDate(ADate DATE)
RETURNS (Year INTEGER, Month INTEGER, Day INTEGER)
AS
BEGIN
EXECUTE PROCEDURE Year(ADate) RETURNING_VALUES Year;
EXECUTE PROCEDURE Month(ADate) RETURNING_VALUES Month;
EXECUTE PROCEDURE Day(ADate) RETURNING_VALUES Day;
END
#
CREATE PROCEDURE ElapsedDays(Date1 DATE, Date2 DATE)
RETURNS (Result INTEGER)
AS
BEGIN
Result = Date2-Date1;
END
#
/* This procedure calculates the modulus of two number */
CREATE PROCEDURE Modulus(Dividend INTEGER, Divisor INTEGER)
RETURNS (Result INTEGER)
AS
BEGIN
IF(Dividend = 0) THEN Result = 0;
ELSE
Result = Dividend-(CAST((Dividend / Divisor)-0.5 AS INTEGER)*Divisor);
END
#
/* This procedure returns the number of the day of the week:
0 - Monday; 1 - Tuesday; 2 - Wdnesday; 3 - Thursday; 4 - Friday; 5 - Saturday; 6 - Sunday
*/
CREATE PROCEDURE DayOfWeek(ADate DATE)
RETURNS (Result INTEGER)
AS
DECLARE VARIABLE Elapsed INTEGER;
BEGIN
EXECUTE PROCEDURE ElapsedDays("1.1.96", ADate) RETURNING_VALUES Elapsed;
EXECUTE PROCEDURE Modulus(Elapsed, 7) RETURNING_VALUES Result;
END
#
CREATE PROCEDURE Time(ADate DATE)
RETURNS (Hour INTEGER, Minute INTEGER)
AS
DECLARE VARIABLE Year INTEGER;
DECLARE VARIABLE Month INTEGER;
DECLARE VARIABLE Day INTEGER;
DECLARE VARIABLE WorkDate DATE;
DECLARE VARIABLE Percent DOUBLE PRECISION;
DECLARE VARIABLE WorkHour DOUBLE PRECISION;
BEGIN
EXECUTE PROCEDURE DecodeDate(ADate) RETURNING_VALUES(Year, Month, Day);
EXECUTE PROCEDURE EncodeDate(Year, Month, Day) RETURNING_VALUES(WorkDate);
Percent = ADate - WorkDate;
WorkHour = Percent *24;
Hour = WorkHour -0.5;
Minute = (WorkHour - Hour) *60 -0.5;
END
#
CREATE PROCEDURE DaysOfMonth(AYear INTEGER, AMonth INTEGER)
RETURNS (Result INTEGER)
AS
DECLARE VARIABLE WorkDate DATE;
BEGIN
Result = 31;
WHILE (Result > 28 AND WorkDate IS NULL) DO
BEGIN
EXECUTE PROCEDURE EncodeDate(AYear, AMonth, Result) RETURNING_VALUES(WorkDate);
WHEN ANY DO Result = Result -1;
END
END
#
CREATE PROCEDURE DayOfYear(ADate DATE)
RETURNS (Result INTEGER)
AS
DECLARE VARIABLE WorkYear INTEGER;
DECLARE VARIABLE WorkMonth INTEGER;
DECLARE VARIABLE I INTEGER;
BEGIN
Result = 0;
EXECUTE PROCEDURE Year(ADate) RETURNING_VALUES(WorkYear);
EXECUTE PROCEDURE Month(ADate) RETURNING_VALUES(WorkMonth);
WorkMonth = WorkMonth-1;
WHILE (WorkMonth > 0) DO
BEGIN
EXECUTE PROCEDURE DaysOfMonth(WorkYear, WorkMonth) RETURNING_VALUES(I);
Result = Result+I;
WorkMonth = WorkMonth-1;
END
EXECUTE PROCEDURE Day(ADate) RETURNING_VALUES(I);
Result = Result +I;
END
#
/*
This procedure is based on the idea of George Kozaderov.
Address: 19-17, Engels st.,Ryazan, 390010, Russia
e-mail: relmail@geo.ryazan.ru
*/
CREATE PROCEDURE AddMonth(ADate DATE, AMonth INTEGER)
RETURNS (Result DATE)
AS
DECLARE VARIABLE Year INTEGER;
DECLARE VARIABLE Month INTEGER;
DECLARE VARIABLE Day INTEGER;
DECLARE VARIABLE Mod INTEGER;
DECLARE VARIABLE DaysOfMOnth INTEGER;
BEGIN
EXECUTE PROCEDURE DecodeDate(ADate) RETURNING_VALUES(Year, Month, Day);
IF(AMonth < 0) THEN
BEGIN
AMonth = AMonth * -1;
Year = Year - CAST(((AMonth-1)/12)-0.49 AS INTEGER) -1;
AMonth = AMonth -1;
EXECUTE PROCEDURE Modulus(AMonth, 12) RETURNING_VALUES(Mod);
AMonth = 12 - (Mod+1);
Month = Month + AMonth;
END
ELSE
BEGIN
Year = Year + CAST(((AMonth-1)/12)-0.49 AS INTEGER);
AMonth = AMonth -1;
EXECUTE PROCEDURE Modulus(AMonth, 12) RETURNING_VALUES(Mod);
Month = Month + Mod +1;
END
IF(Month > 12) THEN
BEGIN
Year = Year +1;
Month = Month -12;
END
EXECUTE PROCEDURE DaysOfMonth(Year, Month) RETURNING_VALUES (DaysOfMonth);
IF(Day > DaysOfMonth) THEN Day = DaysOfMonth;
EXECUTE PROCEDURE EncodeDate(Year, Month, Day) RETURNING_VALUES (Result);
END
#
SET TERM ; #
