Чтение онлайн

на главную - закладки

Жанры

Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Борри Хелен

Шрифт:

Для следующей таблицы, определенной в диалекте 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);

Поскольку ограничение CHECK было определено в диалекте 1, оно вернет частное 0.666666666666667, и строка будет соответствовать условию CHECK.

Обратное также

верно. Если то же ограничение CHECK было добавлено в базу данных диалекта 1 из клиента диалекта 3, то для ограничения будет сохранена арифметика диалекта 3. Предыдущий оператор INSERT не будет выполнен, потому что проверка вернет значение частного 0, которое нарушает это ограничение.

! ! !

СОВЕТ. Мораль всего этого: используйте базы данных диалекта 3 и всегда соединяйтесь с ними, применяя диалект 3. Если вы собираетесь использовать Firebird, то обновите все существующие базы данных до диалекта 3 - желательно описав новую базу данных и поместив в нее ваши старые данные - таким образом вы сохраните покой и сможете избежать уймы неприятных сюрпризов.

. ! .

Умножение и деление

Если оба операнда являются точными числами, умножение операндов даст точное число с масштабом, равным сумме масштабов операндов. Например,

CREATE TABLE t1 (

n1 NUMERIC(9,2),

n2 NUMERIC (9,3) ) ;

COMMIT;

INSERT INTO t1 VALUES (12.12, 123.123);

COMMIT;

Следующий запрос возвращает число 1492.25076, потому что n1 имеет масштаб 2, а n2 - масштаб 3. Сумма масштабов 5.

SELECT n1*n2 FROM t1

В диалекте 3 точность результата умножения чисел с фиксированной точкой будет равна 18. Нужно принять меры предосторожности, чтобы быть уверенным, что не будет переполнения результата при распространении масштаба в умножении.

В диалекте 1, если распространение масштаба приводит к тому, что вычисление даст результат с точностью больше 9, то результатом будет DOUBLE PRECISION.

Сложение и вычитание

Если все операнды являются точными числами, то сложение и вычитание операндов даст точное число с масштабом, равным максимальному масштабу операндов. Например,

CREATE TABLE t1 (

n1 NUMERIC(9, 2) ,

n2 NUMERIC(9, 3)) ;

COMMIT;

INSERT INTO t1 VALUES (12.12, 123.123);

COMMIT;

SELECT n1 + n2 FROM t1;

Этот запрос возвращает 135.243, выбирая максимальный масштаб операндов. Аналогично, следующий запрос возвращает число -111.003:

SELECT n1 - n2 FROM t1;

В диалекте 3 результат любого сложения или вычитания имеет тип NUMERIC(18,n). В диалекте 1 он имеет тип NUMERIC (9, n), где n - масштаб максимального операнда.

Числовой ввод и показатели степени

Любые числовые строки в DSQL, которые могут быть сохранены как DECIMAL(18,S), вычисляются без потери точности, что могло бы произойти при промежуточном сохранении в виде DOUBLE. Синтаксический анализатор DSQL можно заставить распознавать числовые строки как числа с плавающей точкой при использовании научной нотации - если добавить символ "е" или "Е" перед показателем степени, который может быть нулевым.

Поделиться:
Популярные книги

Цветы сливы в золотой вазе, или Цзинь, Пин, Мэй

Ланьлинский насмешник
Старинная литература:
древневосточная литература
7.00
рейтинг книги
Цветы сливы в золотой вазе, или Цзинь, Пин, Мэй

Кодекс Охотника. Книга XIX

Винокуров Юрий
19. Кодекс Охотника
Фантастика:
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XIX

70 Рублей - 2. Здравствуй S-T-I-K-S

Кожевников Павел
Вселенная S-T-I-K-S
Фантастика:
боевая фантастика
постапокалипсис
5.00
рейтинг книги
70 Рублей - 2. Здравствуй S-T-I-K-S

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Лучше подавать холодным

Аберкромби Джо
4. Земной круг. Первый Закон
Фантастика:
фэнтези
8.45
рейтинг книги
Лучше подавать холодным

Имперец. Земли Итреи

Игнатов Михаил Павлович
11. Путь
Фантастика:
героическая фантастика
боевая фантастика
5.25
рейтинг книги
Имперец. Земли Итреи

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи

Ваше Сиятельство 2

Моури Эрли
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Ваше Сиятельство 2

Не грози Дубровскому!

Панарин Антон
1. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому!

Отмороженный 7.0

Гарцевич Евгений Александрович
7. Отмороженный
Фантастика:
рпг
аниме
5.00
рейтинг книги
Отмороженный 7.0

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита

Энфис 5

Кронос Александр
5. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 5

Опасная любовь командора

Муратова Ульяна
1. Проклятые луной
Фантастика:
фэнтези
5.00
рейтинг книги
Опасная любовь командора

Найди меня Шерхан

Тоцка Тала
3. Ямпольские-Демидовы
Любовные романы:
современные любовные романы
короткие любовные романы
7.70
рейтинг книги
Найди меня Шерхан