![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
![]() с базами данных только разбираться начал, поэтому извиняюсь за простой вопрос. Как с помощью генератора и триггера делать автоинкрементные поля я понял, только вот если триггер стоит на before insert и пользователь ввел некорректные данные, то из-за ошибки запись в базу не добавится, а значение генератора все равно увеличится. Можно ли как-то в триггере (или как по другому) перед инкрементом генератора проверять корректность вводимых данных. Заранее спасибо
|
#2
|
|||
|
|||
![]() Цитата:
![]() |
#3
|
||||
|
||||
![]() Значение генератора увеличивается при вызове генератора а не триггера. Тут возможно несколько вариантов. Можно сделать несколько триггеров на одну таблицу. Можно сделать несколько генераторов. Можно проверки делать в программе, и даже генератор из программы вызывать, (FIBPLUS например может так делать). Смотря что вам важнее. Можно сделать автоинкремент непрерывный, если предполагается только один пользователь. Но если база многопользовательская, то возникнут проблемы. Вот здесь очень хорошо всё описано:
http://www.delphisources.ru/forum/sh...0&postcount=19 - Товарищ прапорщик!!! Остановите поезд!!! - Поезд СТОЙ! РАЗ! ДВА! |
#4
|
|||
|
|||
![]() Цитата:
![]() |
#5
|
||||
|
||||
![]() Цитата:
- Товарищ прапорщик!!! Остановите поезд!!! - Поезд СТОЙ! РАЗ! ДВА! Последний раз редактировалось Viajero, 12.08.2011 в 16:01. |
#6
|
|||
|
|||
![]() проблема известная.
Действительно при неверном вводе номер, выделенный триггером, пропадает и в нумерации появляются пропуски (после накладной № 100 следующая накладная имеет №102.) Это происходит потому что генератор работает вне транзакции и поэтому назад не откатывается. Объясни своим юзерам что так работает абсолютно любая БД. Это вопрос безопасности. Первичный ключ никогда не должен повторяться. Но проблему можно решить. 1 способ. Анализируешь введенные данные и записываешь в БД только если они корректны. Поскольку здесь нельзя переводить БД в состояние INSERT то нельзя использовать компоненты связанные с БД (Вместо DBEdit надо использовать Edit и тд) 2 способ. Делаешь в БД процедуру которая возвращает максимальный номер, например SELECT MAX(Num_Nakladn) FROM Table_Nakladn далее программно его инкрементируешь и записываешь всю строку в БД Но при многопользовательской работе могут быть проблемы 3. Можно еще заняться извращениями и программно изменять значение генератора, но проблем будет еще больше. |
#7
|
||||
|
||||
![]() Цитата:
Цитата:
- Товарищ прапорщик!!! Остановите поезд!!! - Поезд СТОЙ! РАЗ! ДВА! |
#8
|
|||
|
|||
![]() В общем, получается что-то вроде этого
Код:
/***************************************************** База данных программы Nikonov по заказу Никонова ******************************************************/ SET AUTODDL ON; SET ECHO ON; OUTPUT isql.txt; CONNECT 'test.fdb' USER 'sysdba' PASSWORD 'masterkey'; DROP DATABASE; COMMIT; SET NAMES WIN1251; SET SQL DIALECT 3; CREATE DATABASE 'test.fdb' USER 'sysdba' PASSWORD 'masterkey' DEFAULT CHARACTER SET WIN1251; COMMIT; CONNECT 'test.fdb' USER 'sysdba' PASSWORD 'masterkey'; /*************************************************** Список операторов ****************************************************/ CREATE TABLE Nakladn ( NN INTEGER NOT NULL, /*первичный ключ*/ NumNakladn INTEGER NOT NULL UNIQUE, /* номер накладной */ Fam VARCHAR(20) NOT NULL, /* фамилия */ Doljn VARCHAR(20), /* должность */ PRIMARY KEY(NN) ); CREATE GENERATOR Nakladn_NN_GEN; SET GENERATOR Nakladn_NN_GEN TO 0; CREATE GENERATOR Nakladn_Num_GEN; SET GENERATOR Nakladn_Num_GEN TO 0; SET TERM !; /********************************************** Процедуры и функции ***********************************************/ /********************************************** Генераторы первичных ключей ***********************************************/ CREATE TRIGGER Nakladn_trig FOR Nakladn ACTIVE BEFORE INSERT AS BEGIN NEW.NN=GEN_ID(Nakladn_NN_GEN,1); END! CREATE TRIGGER Nakladn_Num_trig FOR Nakladn ACTIVE AFTER INSERT AS BEGIN UPDATE Nakladn SET NumNakladn=GEN_ID(Nakladn_Num_GEN,1) WHERE (NN=NEW.NN); END! /*********************************************** Начальная инициализация ************************************************/ SET TERM ;! COMMIT; |