Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
Преобразование DATE или TIMESTAMP создает дату в формате ISO (CCYY-MM-DD). Полная длина выходной строки 10 символов для DATE и 11 - для TIMESTAMP (дата и один пробел перед временем). Нужно 13 символов для TIME или для времени в TIMESTAMP.
Например, выражение
SELECT CAST(timestamp_col as CHAR(24)) AS TstampTxt FROM RDB$DATABASE;
даст строку вроде следующей:
2004-06-25 12:15:45.2345
Это выдаст исключение переполнения:
SELECT CAST (timestamp_col as CHAR(20)) AS TstampTxt FROM RDB$DATABASE;
Двойное преобразование создает правильную строку:
SELECT FIRST 1 CAST (
CAST (timestamp_col AS DATE) AS CHAR(10)) FROM Table1;
Результатом
2004-06-25
К сожалению, нет возможности путем прямого преобразования получить строку, содержащую дату плюс время без дробных долей секунды. Это может быть выполнено с использованием сложного выражения, включающего функции CAST и EXTRACT. Пример см. в одном из следующих подразделов разд. "Функция EXTRACT".
Дата в типе данных DATE диалекта 1 преобразуется в формат DD-MMM-CCYY, а не В формат ISO, как в диалекте 3. Например, вот это
SELECT CAST(dldate_col as CHAR(25)) AS DateTimeTxt FROM RDB$DATABASE;
даст
26-JUN-2004 12:15:45.2345
Следовательно, преобразование дат в диалекте 1 требует 11 символов вместо 10 плюс 1 символ пробела плюс 13 для времени - всего 25.
Преобразование может использовать более сложные выражения в комбинации с другими выражениями, например:
SELECT CAST (10 + CAST(('TODAY') AS DATE) AS CHAR(25)) TEXTTIME FROM RDB$DATABASE;
или
SELECT CAST (10 + CURRENT_TIMESTAMP) AS DATE) AS CHAR(25)) TEXTTIME FROM RDB$DATABASE;
возвращает текстовую строку, показывающую дату на 10 дней позже текущей даты.
Преобразования между типами дата/время и другими типами данных
Любой символьный тип или выражение, чье содержание может быть выражено в правильном литерале даты, может быть преобразовано в соответствующий тип дата/время.
Типы данных времени и даты не могут быть участниками преобразований в типы или из типов SMALLINT, INTEGER, FLOAT, DOUBLE_PRECISION, NUMERIC, DECIMAL или BLOB.
Использование преобразований
Импорт данных дата/время, созданных в другом месте, - например, в другой системе базы данных, во включающем языке или в устройстве получения даты - обычно требует некоторых предварительных действий, прежде чем данные дата/время могут быть помещены в базу данных Firebird.
Большинство включающих языков программирования не поддерживают типы данных DATE, TIME и TIMESTAMP, представляя их внутренне в виде строк или структур. Устройства ввода данных обычно сохраняют дату и время в строках различных форматов и стилях. Типы дата/время чаще всего являются несовместимыми в различных базах данных.
Преобразование обычно требует вычисления и декодирования содержимого элементов даты в исходных данных. Второй частью процесса является реконструкция декодированных элементов и передача их SQL Firebird каким-нибудь способом. Во включающем языке, в котором не существует никакого способа передачи типов данных дата/время Firebird, использование функции CAST в комбинации с допустимыми текстовыми строками для обработки в Firebird в качестве литералов даты может оказаться очень полезным [27] .
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 перечисляет элементы, доступные для каждого типа дата/время.