Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
Использование преобразований
Импорт данных дата/время, созданных в другом месте, - например, в другой системе базы данных, во включающем языке или в устройстве получения даты - обычно требует некоторых предварительных действий, прежде чем данные дата/время могут быть помещены в базу данных Firebird.
Большинство включающих языков программирования не поддерживают типы данных DATE, TIME и TIMESTAMP, представляя их внутренне в виде строк или структур. Устройства ввода данных обычно сохраняют дату и время в строках различных форматов и стилях. Типы дата/время чаще всего являются несовместимыми в различных базах данных.
Преобразование обычно требует вычисления
27
API предоставляет программистам две полезные функции для преобразования структуры дата/время клиентского языка в формат Firebird и из формата Firebird. См. в документе фирмы Borland "API Guide" (Руководство по API) описание функций isc_encode_date и isc_decode_date.
В некоторых случаях сохранение внешних данных в текстовых файлах в форматах литералов даты может быть лучшим решением. Firebird может открывать такие файлы, как входные таблицы в модулях на серверной стороне - хранимые процедуры или триггеры - и использовать CAST и другие функции для обработки данных в столбцах даты/времени в родных таблицах. Более подробную информацию см. в разд. "Использование внешних файлов в качестве таблицы " главы 16.
Функция CAST также может быть использована для подготовки внутренних данных для экспорта.
Такие ситуации появляются, когда использование CAST в предложении WHERE с типами дата/время решает логические проблемы сравнения столбца одного типа со столбцом другого типа данных.
Предположим, что нам нужно объединить таблицу покупателей, которая содержит столбец BALANCE_DATE типа DATE с таблицей транзакций покупателя, которая имеет столбец TRANSUDATE типа TIMESTAMP. Нам нужно создать предложение WHERE, которое выбирает набор данных, содержащий неоплаченные транзакции для текущего покупателя, появившиеся не позднее BALANCE_DATE. Мы можем попытаться:
SELECT ...
WHERE COST_TRANS.TRANSDATE <= CUSTOMER.BALANCE_DATE ;
Этот критерий не даст нам того, что мы хотим! Он найдет все строки транзакций после полуночи даты BALANCE_DATE, потому что он вычислит BALANCE_DATE с временем 00:00:00. Любая транзакция после полуночи этой даты не будет соответствовать критерию поиска.
Что мы действительно хотим, так это включить все транзакции, где дата из TRANS DATE соответствует BALANCE_DATE. Преобразование TRANSUDATE в тип DATE сохраняет день:
SELECT ...
WHERE CAST (CUST_TRANS.TRANSDATE AS DATE) <= CUSTOMER.BALANCE_DATE;
Диалект 3 предоставляет более богатую поддержку типов дата/время, чем диалект 1. Одной из задач, которая, скорее всего, привлечет ваше внимание, если вы выполняете такое преобразование, является замена существующих в диалекте 1 столбцов типа DATE (который эквивалентен типу TIMESTAMP в диалекте 3) путем преобразования их в типы данных диалекта 3 DATE (только дата) или TIME (только время), CAST легко выполняет эту работу.
Пример одного из стилей преобразования с использованием CAST см. в конце этой главы.
Функция EXTRACT
Функция EXTRACT возвращает различные элементы, выделенные путем декодирования полей типов дата/время. Она может работать с полями дата/время в диалекте 3 и в диалекте 1.
Синтаксис
Синтаксис функции EXTRACT:
EXTRACT (элемент FROM
элемент должен быть одним из допустимых элементов в типе данных поле. Не все элементы допустимы для всех типов данных дата/время. Тип данных элемента изменяется в соответствии с выделяемым элементом. Табл. 10.10 перечисляет элементы, доступные для каждого типа дата/время.
Поле может быть столбцом, переменной или выражением, результатом вычисления которого является поле дата/время.
Табл. 10.10 показывает ограничения на аргументы и их типы данных при использовании функции EXTRACT.
Таблица 10.10. Аргументы, типы и ограничения функции EXTRACT
Элемент | Тип данных | Ограничения | TIMESTAMP/ диалект 1 DATE | DATE | TIME |
YEAR | SMALLINT | 0-5400 | Допустимо | Допустимо | Не допустимо |
MONTH | SMALLINT | 1-12 | Допустимо | Допустимо | Не допустимо |
DAY | SMALLINT | 1-31 | Допустимо | Допустимо | Не допустимо |
HOUR | SMALLINT | 0-23 | Допустимо | Не допустимо | Допустимо |
MINUTE | SMALLINT | 0-59 | Допустимо | Не допустимо | Допустимо |
SECOND | DECIMAL(6,4) | 0-59.9999 | Допустимо | Не допустимо | Допустимо |
WEEKDAY | SMALLINT | 0-6* | Допустимо | Допустимо | Не допустимо |
YEARDAY | SMALLINT | 1-366 | Допустимо | Допустимо | Не допустимо |
* 0 = воскресенье ... 6 = суббота.
Объединение EXTRACT с другими функциями
Далее следуют два примера использования функции EXTRACT внутри CAST для получения представлений даты, которые не могут быть получены использованием одной из функций.
Хотя невозможно прямым преобразованием получить строку даты и времени без долей секунды, это может быть сделано при использовании выражения, включающего обе функции CAST и EXTRACT.
Эта техника больше нужна в диалекте 1, чем в диалекте 3. Тем не менее она может быть экстраполирована на любой тип даты или времени диалекта 3, если вам нужно сохранять время дня в виде строки.
Функция EXTRACT делает возможным выделение отдельных элементов типов даты и времени в значения SMALLINT. Следующий триггер выделяет элементы времени из столбца диалекта 1 DATE с именем CAPTURE_DATE и преобразует их в CHAR (13), имитируя стандартный в Firebird литерал времени 'HH:MM:ss.nnnn'.