Читать интересную книгу Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 28 29 30 31 32 33 34 35 36 ... 238

Следующая строка:

SELECT GEN_ID(AGenerator, 0) from RDB$DATABASE;

возвращает текущее значение генератора без его увеличения[18].

PSQL, язык программирования Firebird, позволяет напрямую присваивать сгенерированное значение переменной:

. . .

DECLARE VARIABLE MyVar BIGINT;

. . .

MyVar = GEN_ID(AGenerator, 1);

Более подробную информацию об использовании генераторов в модулях PSQL - в особенности в триггерах - см. в главе 29[19].

Использование отрицательного шага

Аргумент шаг в GEN_ID может быть отрицательным. Следовательно, можно устанавливать или переустанавливать текущее значение генератора, передавая отрицательный аргумент или в виде целой константы, или в виде целого выражения. Эта возможность иногда используется как "трюк" для установки значений генератора в PSQL, поскольку в PSQL не могут использоваться такие команды DDL, как SET GENERATOR.

Например, оператор:

SELECT GEN_ID (AGenerator, -GEN_ID (AGenerator, 0)) from RDB$DATABASE;

устанавливает значение генератора в ноль.

Предупреждения о переустановке значений генераторов

Основное простое правило по переустановке значений генераторов в работающей базе данных - будь то в SQL, PSQL или в некотором интерфейсе администратора - не делать этого.

Основное достоинство значений генератора то, что они гарантированно являются уникальными. В отличие от других доступных пользователю операций Firebird генераторы работают вне контекста транзакций. Однажды сгенерированное, число установлено и не может быть изменено отменой транзакции. Это дает полную уверенность в том, что ничто не может вмешиваться в целостность последовательности чисел, предоставляемых генератором.

Оставьте переустановку значений генераторов в создаваемой базе данных для редких случаев, когда это требуется условиями проектирования. Например, некоторые бухгалтерские системы, написанные в старом стиле, передают журналы в таблицы истории с новым первичным ключом, очищают таблицу журналов и устанавливают последовательность первичных ключей в ноль в организациях с несколькими филиалами, выделяя диапазоны значений ключа каждого филиала в отдельный "фрагмент", чтобы гарантировать целостность ключей при репликации.

Никогда не переустанавливайте значения генератора в попытке скорректировать программные ошибки, ошибки ввода данных или для "устранения промежутков" в последовательности значений[20].

Масштабируемые типы с фиксированной точкой

Типы с фиксированной точкой позволяют управлять числами, которые должны вычисляться с дробной частью, задающейся количеством цифр после десятичной точки, или масштабом. Обычно масштабируемые типы нужны для финансовых значений и других чисел, которые являются результатом подсчета или выполнения арифметических операций над целыми элементами и частями элементов.

Предсказуемость результатов умножения и деления чисел с фиксированной точкой позволяет выбрать их для хранения денежных значений. Тем не менее, поскольку типы с фиксированной точкой имеют ограниченные "рамки", в которых могут размещаться числа, они являются причиной появления исключений переполнения или потери значимости возле их верхней и нижней границы. В странах, где единицы валюты представляют небольшие значения, нужно быть внимательным при выборе ограничений чисел.

Например, следующий оператор использует ставку налога (DECIMAL(5,4)) и чистую прибыль (NUMERIC (18, 2)):

UPDATE ATABLE

SET INCOME_AFTER_TAX = NET_PROFIT - (NET_PROFIT * TAX_RATE) ;

Пусть ставка налога будет 0.3333.

Пусть чистая прибыль будет 1234567890123456.78.

Результат:

ISC ERROR CODE:335544779

Integer overflow. The result of an integer operation caused the most significant bit of the result to carry.

(Переполнение целого числа. Результат целочисленной операции привел к переносу большинства значащих битов)

Firebird предоставляет два типа данных чисел с фиксированной точкой или масштабируемых: NUMERIC и DECIMAL. Каждый масштабируемый тип объявляется как TYPE(p, s), где p определяет точность (количество значащих цифр), а s - масштаб (размещение десятичной точки - т. е. количество цифр справа от символа десятичной точки).

В соответствии со стандартом SQL-92 оба типа NUMERIC и DECIMAL ограничивают хранимое число объявленным масштабом. Различие между этими двумя типами заключается в способе, каким ограничивается точность. Точность должна быть такой, "как объявлено" для столбцов типа NUMERIC, в то время как столбцы DECIMAL могут получать числа, чья точность по меньшей мере равна тому, что было объявлено, больше границы реализации.

Типы NUMERIC и DECIMAL, как они реализованы в Firebird, являются идентичными, за исключение случая, когда точность меньше пяти. Оба типа действительно соответствуют стандарту типа DECIMAL, NUMERIC не соответствует SQL-92.

Внутренне Firebird хранит масштабированное число как типы SMALLINT(16 бит), INTEGER (32 бита) или BIGINT(64 бита) в соответствии с объявленным размером точности. Его объявленная точность[21] сохраняется вместе с объявленным масштабом в виде отрицательного множителя масштаба[22], представляющего степень числа 10. Когда к числу происходит обращение для вывода или для расчетов, оно получается произведением хранимого целого на 10 в степени "множитель масштаба" ( 10(^множитель масштаба^) )

Например, для столбца, объявленного как NUMERIC(4,3), Firebird сохраняет внутренне число в виде SMALLINT. Если вы вводите число 7.2345, Firebird без сообщений округляет самую правую цифру (4) и сохраняет 16-битовое целое 7235 и множитель масштаба -3. Это число будет найдено как 7.235 (7235 * 10(^-3^)).

Тип данных NUMERIC

Формат типа данных NUMERIC:

NUMERIC(p,s)

Например, NUMERIC (4,2) определяет число, состоящее не более чем из четырех цифр, включая две цифры справа от десятичной точки. Следовательно, числа 89.12 и 4.321 будут сохранены в столбце NUMERIC(4,2) как 89.12 и 4.32 соответственно. Во втором примере последняя цифра 10(^-3^) выходит за пределы масштаба и просто отбрасывается.

И все же возможно хранение в этом столбце числа с большей точностью, чем было объявлено. Максимально здесь может быть 327.67 - т. е. число с точностью 5. Поскольку база данных хранит фактическое число как SMALLINT, числа не начинают вызывать ошибки переполнения, пока внутренне хранимое число не станет больше 32,767 или меньше -32,768.

Тип данных DECIMAL

Формат типа данных DECIMAL:

DECIMAL(Р, S)

Как и в случае NUMERIC, DECIMAL(4,2) определяет число, состоящее, по меньшей мере, из четырех цифр, включая две цифры справа от десятичной точки. Тем не менее, поскольку Firebird сохраняет данные DECIMAL с точностью 4 и меньше как INTEGER, этот тип может в столбце DECIMAL(4,1) потенциально хранить число от 214 748 364 до -214 748 364.8 без появления ошибки переполнения.

Точные числа могут быть перепутаны, не только по причине тонкой разницы между этими двумя типами, но и потому, что диалект базы данных влияет на доступный диапазон точности. Табл. 9.2 может служить руководством по тому, какую точность и масштаб вам нужно указать для различных требований к вашим числам.

Таблица 9.2. Диапазон и способ хранения в Firebird типов данных NUMERIC и DECIMAL

Точность

Тип

Диалект 1

Диалект 3

1-4

NUMERIC

SMALLINT

SMALLINT

1-4

DECIMAL

INTEGER

INTEGER

5-9

NUMERIC и DECIMAL

INTEGER

INTEGER

10-18

NUMERIC и DECIMAL

BIGINT

DOUBLE PRECISION*

* Точные числа с точностью больше чем 9, могут быть объявлены в диалекте 1 базы данных без появления исключения. Эти числа будут храниться как DOUBLE PRECISION и будут подчиняться тем же самым ограничениям точности, что и любые числа с плавающей точкой. В процессе преобразования базы данных диалекта 1 в диалект 3 клиент диалекта 2, открыв таблицу, содержащую столбцы DECIMAL или NUMERIC с точностью, большей 9, получит сообщение об ошибке. Более подробную информацию о преобразованиях диалекта 1 в диалект 3 см. в разд. "Специальная тема миграции: диалекты SQL" главы 8.

Конвертированные базы данных

Если база данных диалекта 1 была обновлена до диалекта 3 с использованием создания резервной копии gbak, а затем восстановлена, то числовые поля, определенные с точностью, большей 9, сохранят тип данных DOUBLE PRECISION. Хотя они будут представлены так, как были вначале определены (например, NUMERIC (15,2)), они будут сохраняться и использоваться в вычислениях как DOUBLE PRECISION.

Более подробную информацию о преобразованиях баз данных диалекта 1 в диалект 3 см. в разд. "Специальная тема миграции: диалекты SQL" главы 8.

Специальные ограничения в статическом SQL

Включающий язык встроенных приложений не может использовать или распознавать малые точности типов данных NUMERIC или DECIMAL С дробной частью, когда они внутренне хранятся как типы SMALLINT или INTEGER. для устранения такой проблемы в любой базе данных, к которой предполагается доступ из таких встроенных приложений (ESQL):

* не определяйте столбцы или домены с типом NUMERIC или DECIMAL малой точности в базе данных диалекта 1. или храните данные как целые и пишите в приложениях код, учитывающий масштаб, или используйте DOUBLE PRECISION и применяйте подходящий алгоритм округления для вычислений;

1 ... 28 29 30 31 32 33 34 35 36 ... 238
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри.
Книги, аналогичгные Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Оставить комментарий