FirebirdSQL logo

DECIMAL

Формат объявления данных
  DECIMAL
| DECIMAL(precision)
| DECIMAL(precision, scale)
Table 1. Параметры типа DECIMAL
Параметр ^^ Описание

precision

Точность. Может быть в диапазоне от 1 до 38.По умолчанию 9.

scale

Масштаб. Может быть в диапазоне от 0 до precision.По умолчанию 0.

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

Приведём примеры того, как СУБД хранит данные в зависимости от формы их объявления:

DECIMAL(4)    stored as   INTEGER (exact data)
DECIMAL(4,2)              INTEGER (data * 102)
DECIMAL(10,4) (Dialect 1) DOUBLE PRECISION
              (Dialect 3) BIGINT (data * 104)
DECIMAL(38, 6)            INT128 (data * 106)

Точность арифметических операций

Функции MIN, MAX, SUM, AVG работают со всеми точными числовыми типами.SUM и AVG являются точными, если обрабатываемая запись имеет точный числовой тип, а масштабированная сумма соответствует 64 или 128 битам: в противном случае возникает исключение переполнения.SUM и AVG никогда не вычисляются с использованием арифметики с плавающей запятой, если тип данных столбца не является приблизительным числом.

Функции MIN и MAX для точного числового столбца возвращают точный числовой результат, имеющий ту же точность и масштаб, что и столбец.SUM и AVG для точного числового типа возвращает результат типа NUMERIC ({18 | 38}, S) или DECIMAL ({18 | 38}, S), где S - масштаб столбца.Стандарт SQL определяет масштаб результата в таких случаях, в то время как точность SUM или AVG для столбцов с фиксированной точкой определяется реализацией: мы определяем его как 18 или 38 (если точность аргумента 18 или 38).

Если два операнда OP1 и OP2 являются точными числами с масштабами S1 и S2 соответственно, то OP1 + OP2 и OP1 - OP2 являются точными числами с точностью 18 или 38 (если один из аргументов с точностью 38) и масштабом равному наибольшему из значений S1 и S2, тогда как для OP1 * OP2 и OP1 / OP2 являются точными числами с точностью 18 или 38 (если точность аргументов 18 или 38) и шкалой S1 + S2.Масштабы этих операций, кроме разделения, определяются стандартом SQL.Точность всех этих операций и масштаб при делении стандартом не регламентируются, а определяются реализацией: Firebird определяет точность как 18 или 38 (если точность аргументов 18 или 38), а масштаб деления как S1 + S2, такой же, что определён стандартом в для умножения.

Всякий раз, когда выполняется арифметические операции с точными числовыми типами, в случае потери точности будет сообщено об ошибке переполнения, а не возвращено неправильное значение. Например, если столбец DECIMAL (18,4) содержит наиболее отрицательное значение этого типа, -922337203685477.5808, попытка разделить этот столбец на -1 будет сообщать об ошибке переполнения, поскольку истинный результат превышает наибольшее положительное значение, которое может быть представлено в типе, а именно 922337203685477.5807.

Если один операнд является точным числом, а другой приблизительным числом, то результатом любого из четырёх диадических операторов будет типа DOUBLE PRECISION.(В стандарте говорится, что результат является приблизительным числом с точностью, по крайней мере, такой же как точность приблизительного числового операнда: Firebird удовлетворяет этому требованию, всегда используя DOUBLE PRECISION, поскольку этот тип является максимальным приблизительным числовым типом, который предоставлен в Firebird.)

Типы данных для работы с датой и временем

В СУБД Firebird для работы с данными, содержащими дату и время, используются типы данных DATE, TIME и TIMESTAMP.В 3-м диалекте присутствуют все три вышеназванных типа данных, а в 1-м для операций с датой и временем доступен только тип данных DATE, который не тождественен типу данных DATE 3-го диалекта, а является типом данных TIMESTAMP из 3-го диалекта.

Note

В диалекте 1 тип DATE может быть объявлен как TIMESTAMP.Такое объявление является рекомендуемым для новых баз данных в 1-м диалекте.

Доли секунды

В типах TIMESTAMP и TIME Firebird хранит секунды с точностью до десятитысячных долей.Если вам необходима более низкая гранулярность, то точность может быть указана явно в виде тысячных, сотых или десятых долей секунды в базах данных в 3 диалекте и ODS 11 и выше.

Note
Несколько полезных сведений о точности секунд

Временная часть типов TIME или TIMESTAMP представляет собой 4-байтный целое (WORD) вмещающее значение времени с долями секунды, и хранящаяся как количество десятитысячных долей секунды прошедших с полуночи.Фактическая точность значений полученных из time(stamp) функций и переменных будет следующей:

  • CURRENT_TIME — по умолчанию имеет точность до секунды, точность до миллисекунд может быть указана следующим образом CURRENT_TIME (0 | 1 | 2 | 3)

  • CURRENT_TIMESTAMP — по умолчанию имеет точность до миллисекунды, точность от секунд до миллисекунд может быть указана следующим образомCURRENT_TIMESTAMP (0 | 1 | 2 | 3)

  • LOCALTIME — по умолчанию имеет точность до секунды, точность до миллисекунд может быть указана следующим образомLOCALTIME (0 | 1 | 2 | 3)

  • LOCALTIMESTAMP — по умолчанию имеет точность до миллисекунды, точность от секунд до миллисекунд может быть указана следующим образомLOCALTIMESTAMP (0 | 1 | 2 | 3)

  • Литерал 'NOW' имеет точность до миллисекунд;

  • Функции DATEADD и DATEDIFF поддерживают точность до десятых долей миллисекунд.

  • Функция EXTRACT возвращает значения с точностью до десятых долей миллисекунды для аргументов SECOND и MILLISECOND;

Хранение типов с часовыми поясами

Типы данных с поддержкой часовых поясов сохраняются в виде значений в формате UTC (смещение 0) с использованием структуры TIME или TIMESTAMP+ два дополнительных байта для информации о часовом поясе (либо смещение в минутах, либо идентификатор именованного часового пояса).

Хранение в формате UTC позволяет Firebird индексировать и сравнивать два значения в разных часовых поясах.

При хранении в UTC есть некоторые предостережения:

  • Когда вы используете именованные зоны и правила часовых поясов для этой зоны меняются, время в формате UTC остаётся прежним, но местное время в названной зоне может измениться.

  • Для типа данных TIME WITH TIME ZONE при вычислении смещения часового пояса для именованной зоны для получения местного времени в зоне применяются правила, действующие на 1 января 2020 года, чтобы гарантировать стабильное значение.Это может привести к неожиданным или сбивающим с толку результатам.

DATE

В 3-м диалекте тип данных DATE, как это и следует предположить из названия, хранит только одну дату без времени.В 1-м диалекте тип DATE эквивалентен типу TIMESTAMP и хранит дату вместе со временем.

Допустимый диапазон хранения от 01.01.0001 н.э. до 31.12.9999 н.э.

Tip

В случае необходимости сохранять в 1 диалекте только значения даты, без времени, при записи в таблицу добавляйте время к значению даты в виделитерала '00:00:00.0000'.

Example 1. Пример использования DATE
CRETE TABLE DataLog(
  id BIGINT NOT NULL,
  bydate DATE
);
...
AS
  DECLARE BYDATE DATE;
BEGIN
...