Читаем Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ полностью

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

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

* в базе данных диалекта 3 определяйте столбцы или домены любого размера типа NUMERIC и DECIMAL, используя точность не меньше 10, чтобы получить их внутреннее хранение как BIGINT. Указывайте масштаб, если вы хотите управлять точностью и масштабом. Используйте ограничения CHECK, если вам нужно контролировать диапазоны значений.

<p>Поведение типов с фиксированной точкой в операциях</p>Деление

При выполнении деления типов с фиксированной точкой диалекты 1 и 3 ведут себя по-разному.

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

В диалекте 1 деление всегда создает частное типа DOUBLE PRECISION.

Примеры

В диалекте 3 частное от деления DECIMAL(12,3) на DECIMAL(9,2) будет DECIMAL(18,5). Масштабы суммируются:

SELECT 11223344.556/1234567.89 FROM RDB$DATABASE

Это дает 9.09090.

Посмотрим, чем отличается частное, когда этот же запрос выполняется в диалекте 1. Первый операнд трактуется как число DOUBLE PRECISION, потому что его точность (12) превышает максимум масштабируемого типа для диалекта 1. Частное также является числом DOUBLE PRECISION. Результат 9.09090917308727 по причине ошибок, присущих типам с плавающей точкой.

Для следующей таблицы, определенной в диалекте 3, операции деления дают различные результаты.

CREATE TABLE t1 (

i1 INTEGER,

i2 INTEGER,

n1 NUMERIC(16, 2),

n2 NUMERIC(16,2));

COMMIT;

INSERT INTO t1 VALUES (1, 3, 1.00, 3.00);

COMMIT;

Следующий запрос возвращает значение 0.33 типа NUMERIC(18,2), потому что сумма масштабов 0 (операнд 1) и 2 (операнд 2) равна 2:

SELECT i1/n2 from t1

Следующий запрос возвращает значение 0.3333 типа NUMERIC (18,4), потому что сумма масштабов двух операндов равна 4:

SELECT n1/n2 FROM t1

Деление целого на целое

Используя предыдущий пример, следующий запрос в диалекте 3 вернет целое 0, потому что каждый операнд имеет масштаб 0, следовательно, сумма масштабов будет 0:

SELECT i1/i2 FROM t1

В диалекте 1, как и в большинстве других СУБД, деление одного целого на другое целое даст результат с плавающей точкой типа DOUBLE PRECISION:

SELECT 1/3 AS RESULT FROM RDB$DATABASE

Это дает .333333333333333.

Хотя настоящее правило диалекта 1 является интуитивным для языков программирования, оно не соответствует стандарту SQL-92. Целые типы имеют масштаб 0. Для согласованности это требует, чтобы результат (частное) любой операции деления целого на целое соответствовал правилам масштабирования для чисел с фиксированной точкой и был бы целым.

Диалект 3 соответствует стандарту и усекает частное от операций деления целого на целое до целого. Следовательно, следующий оператор является неразумным:

SELECT 1/3 AS RESULT FROM RDB$DATABASE

Он вернет 0.

Если вам нужно сохранить дробную часть в результате (в частном) деления целого на целое в диалекте 3, убедитесь, что у одного из операндов присутствует нужный масштаб, или включите "множитель" в выражение, чтобы гарантировать масштаб результата.

Примеры:

SELECT 1.00/3 AS RESULT FROM RDB$DATABASE

Вернет .33.

SELECT (5 * 1.00)/2 AS RESULT FROM RDB$DATABASE

Этот вернет 2.50.

Диалект 1 базы данных с диалектом 3 клиента

База данных диалекта 1, которая была открыта клиентом диалекта 3, может преподнести некоторые сюрпризы в отношении деления целых чисел. Когда операция выполняет нечто, что приводит к проверке условия CHECK, или выполняется хранимая процедура или триггер, то осуществляемые действия основаны на диалекте, на котором CHECK, хранимая процедура или триггер были определены, а не на действующем диалекте, на котором приложение выполняет проверку, хранимую процедуру или триггер.

Например, в базе данных диалекта 1 таблица содержит столбцы MYCOL1 (INTEGER) и MYCOL2 (INTEGER) и следующее условие CHECK, которое было определено, когда база данных имела диалект 1:

CHECK(MYCOL1 / MYCOL2 >0.5)

Пусть теперь пользователь запускает isql или приложение, задав диалект 3. Программа пытается добавить строку в конвертированную базу данных:

INSERT INTO MYTABLE (COL1, COL2) VALUES (2,3);

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных