Для иллюстрации вычисляемых полей я всегда привожу пример с покупками в магазине, потому что он наиболее наглядный. Допустим, что у нас есть количество товара и его цена, а нужно рассчитать сумму денег, затраченных на каждый товар. Для решения задачи нужно создать таблицу из четырех полей: название, цена, количество, сумма. Давайте удалим старую таблицу TestTable и создадим новую, которая позволит решить поставленную проблему:
CREATE TABLE TestTable ( vcName varchar(50), iCost money, iNumber float, iSumm AS (iCost * iNumber) )
В данном примере у нас создается таблица из 4 полей:
Давайте наполним таблицу строками значений и посмотрим на результат:
Листинг 1.7. Наполнение таблицы значениями
INSERT INTO TestTable(vcName, iCost, iNumber) VALUES('Хлеб', 7.5, 2) INSERT INTO TestTable(vcName, iCost, iNumber) VALUES('Молоко', 17, 3) INSERT INTO TestTable(vcName, iCost, iNumber) VALUES('Печенье', 46, 0.5) INSERT INTO TestTable(vcName, iCost, iNumber) VALUES('Морковь', 12, 0.8) INSERT INTO TestTable(vcName, iCost, iNumber) VALUES('Картофель', 15, 5) SELECT * FROM TestTable
Что выполняется в листинге, нас пока не особо интересует. Достаточно понимать, что в нем в таблицу добавляется пять строк, а в последней строке запрашиваются все строки из таблицы.
В листинге 1.16 во время заполнения таблицы значениями, я заполнял все поля в строках, кроме последнего поля "iSumm". Но не смотря на это, в последнем поле есть значения и они являются результатом перемножения цены товара, на его количество.
Особое внимание нужно уделить строке 4, где показана цена моркови. Я в таблицу заносил значение 0.8, но сервер показал, что там находиться число 0.80000000000000004. Почему? Это погрешность Intel процессора и того, как он хранит вещественные числа. Если вы работали с такими языками программирования как C++, то должны знать, что целое число 1 никогда не будет равно вещественному 1.0, потому что процессор может воспринять вещественную единицу как число 1.00000000000000001, которое уже отличается от целого числа 1. Но если округлить вещественное число, то тогда результат будет равным.
В большинстве языков программирования и в базах данных эта погрешность не убирается на уровне отображения, хотя это достаточно легко. Например, SQL сервер мог бы обрезать последний символ.
Учитывайте эту особенность в своих проектах. Если необходимо, чтобы не было погрешности, то лучше всего использовать вместо типа float тип numeric и явно указывать необходимую точность.
На этот раз на экране нет никакой погрешности, потому что она может быть только в последнем разряде вещественного числа, а мы используем только первые два разряда. Единственное, программа при отображении вещественного числа не отображает ноль перед запятой, т.е. вместо числа "0.8" отображается ".8". Но это уже недочет отображения, а не ошибка и не погрешность, ведь расчеты все верные.