Первое знакомство с базой данных InterBase меня немного огорчило. Создавая свою первую таблицу, я, руководствуясь своим предыдущим опытом создания архитектуры базы данных, создал уникальный целочисленный ключ по первому полю ID. Для обеспечения уникальности этого поля я обычно ставил значение по умолчанию в autoincrement . автоматическое увеличения числового поля. Создавал я таблицу в редакторе IBAdmin и никак не мог поверить, что нет, ставшего уже обычным даже для <Щкарманных> баз данных, свойства поля. Но умные люди говорят так: <ЩЕсли Вы сделали все, что можно, а все равно ничего не получается, то читайте документацию>.
Чтение документации показало, что InterBase , будучи похожей на большинство СУБД, имеет свои уникальные свойства. Одним из них являются генераторы . встроенные в базу данных объекты которые, используя функцию gen_id генерируют уникальные значения числовых полей. Вместо жесткого ограничения в реализации autoincrement, фирма Borland дала в руки программистов целое средство для использования по собственному усмотрению.
Ну раз есть возможность . попытаемся сделать реализацию. Autoincrement я реализовывал поля ID для некоторой таблицы поступления товаров GOODS, показанной для примера показанной сильно упрощенной:
CREATE TABLE GOODS (
ID Integer NOT NULL,
GOODNAME Char(100) NOT NULL CHARACTER SET NONE,
PRICE Numeric(15,4) NOT NULL,
CONSTRAINT GOODS_PK PRIMARY KEY (ID)
COMMIT WORK;
Первым делом я создал генератор:
CREATE GENERATOR GOODS_ID;
Дальше можно было поступить двумя способами. Один из них явный вызов функции gen_id с параметрами (GOODS_ID,1) при обработке события OnBeforeInsert в Delphi. Другой же способ, показавшийся мне более красивым, заключался в написании триггера в базе на это же событие. Одним словом . максимально количество логики помещаем в базу. Триггер получился очень маленьким.
CREATE TRIGGER GOOD_ID_INCREMENT ACTIVE before insert POSITION 0
AS
begin
NEW.ID = GEN_ID (GOODS_ID, 1);
end
Таким образом, перед вставкой записи генератор возвращает значение на 1-цу больше предыдущего. Указав, к примеру, NEW.ID = GEN_ID (GOODS_ID, 10) мы будем получать прирост поля 10-ми и.т.д. Попробуем все это на реальном запросе на вставку данных:
insert into goods (goodname,price)
values (' Чашка программистская с USB подогревом',260.5);
И как результат получаем данные:
ID GOODNAME Price
1 Чашка программистская с USB подогревом 260.5
Вывод: получили то, что хотели.
Ну и что с этого, можете сказать, внимательный читатель. Ради уже реализованной в других СУБД возможности писать целый триггер! В чем сила то брат? А сила здесь в том, что значением генератора можно манипулировать как душе угодно, в отличии от встроенного autoincrement. Вот несколько ситуаций:
1. После написания программы проходило тестирование с добавлением новых записей, счетчик поля все время возрастал. В результате к заказчику пришла база, где номера почему-то начинаются после 300. Можно, конечно, пересоздать таблицу со всеми ее связями, индексами, триггерами и номера в полу пойдут в нормальном порядке. Но, намного проще можно поступить в описанном мною случае. Достаточно выполнить запрос:
DELETE FROM GOODS;
SET GENERATOR GOODS_ID TO 0
2. Иногда значение поля нужно иметь до выполнение вставки записи. Пример с триггером здесь не пройдет, но никто не мешает вызвать функцию GEN_ID (GOODS_ID, 1) из программы.
3. Попробуйте организовать уникальное уменьшение значения поля, например от 1000. Была в моей жизни такая программа. Тогда, не зная еще InterBase , я решил ее построением курсора, при нормальном возрастании. Для данного примера это выглядело бы так:
SELECT 1000 - ID AS ID,GOODNAME, PRICE FROM GOODS
Имея в своем распоряжении генераторы, я бы решил эту задачу другим образом. При первом запуске проекта запрос SET GENERATOR GOODS_ID TO 1000 а дальше, при помощи тригера:
CREATE TRIGGER GOOD_ID_INCREMENT ACTIVE before insert POSITION 0
AS
begin
NEW.ID = GEN_ID (GOODS_ID, -1);
end
Результат . поле уникально уменьшается.
Вот кратко и все. Это только небольшая часть айсберга под названием InterBase -- <Щродной> СУБД для разработчиков на продуктах Borland. Успехов вам, программисты-сетяне
Искренне ваш RollBack
|