Поддерживает-ли IB поля типа autoincrement?
В явном виде нет - вместо этого в IB существует другой механизм, называемый "генераторами". Генератор - некая переменная, значение которой может быть получено и увеличено на некоторое значение (дельту) при помощи встроенной функции GEN_ID. Создать генератор можно фразой:
CREATE GENERATOR MYGENERATOR;
Обычно генераторы используют в триггерах, при этом текст триггера может быть следующим:
Код:
CREATE TRIGGER TI_CLIENTS FOR CLIENTS
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (new.CLIENT_ID IS NULL) THEN
CLIENT_ID = GEN_ID(MYGENERATOR, 1);
END
Вместо значения "1" может быть использовано любое число, на которое нужно иметь приращение текущего значения генератора.
Также новое значение генератора можно получить запросом
SELECT GEN_ID(mygen, 1) from RDB$DATABASE
Механизм генераторов гарантирует что даже при конкурентном (параллельном) вызове функции GEN_ID каждому пользователю будет выдаваться уникальное значение. Последнее значение генератора всегда запоминается в БД, поэтому разработчику не нужно заботиться о "восстановлении" его максимального значения после подсоединения к БД.
Генераторы являются переменными типа integer (longint), таким образом если предположить что новое значение возвращается в среднем с интервалом в 3 секунды, значений генератора хватит приблизительно на 270 лет.
примечание: если вы воспользуетесь приведенным выше примером использования генератора в триггере, то у вас может возникнуть следующая проблема - при добавлении записей с клиентского места новые записи будут "пропадать", или будет появляться сообщение BDE "Record/Key deleted". Это связано с тем, что клиенту никаким образом не может быть передана информация об идентификаторе сформированом в триггере на сервере.
Т.е. новую запись можно будет увидеть только либо перевыполнив запрос либо переместившись в конец таблицы (если еще не произошел fetch всех записей. Для исключения такой ситуации можно создать хранимую процедуру возвращающую значение генератора (так-же как и для триггера), и вызывать эту процедуру _перед_ созданием новой записи (для Delphi - TTable.BeforePost). Вместо процедуры можно использовать приведенный выше запрос select gen_id(mygen, 1) from rdb$database.