Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Автоинкреаментное поле [D7, IB6.x]


Sinus ©   (2006-09-23 17:33:00) 

Привет всем ,
есть БД ( пример из папки CommonFiles\Borland\data ),
при попытке вставить запись в таблицу "Работников" поле ИД
не заполняю и при сохранении записи генерируется исключение
"Поле ID не заполненно ", если же заполняю - необходимо проверять вводимое значени на отсуствие в таблице.
Вопрос по чему автоматически не генерируется число из  генератора и не вставляется в поле ИД ?


_Ламер_   (2006-09-25 19:05:00) [1]

А триггер может получить доступ к системным таблицам, если текущий юзер не имеет его? IB/FB, например.


Desdechado   (2006-09-25 17:46:00) [2]

я предпочитаю получать сгенеренный в триггере ID после успешной вставки записи путем вызова SELECT c уникальной комбинацией полей
тогда никаких коллизий


dr Gonzo   (2006-09-25 14:43:00) [3]

Тут получается размазывания кода в Delphi + SQL = что на мой взгляд глупо.

По идее, возвращаясь к началу темы, у нас должна быть хранимая процедура на сервере вида WorkerAdd (P1,P2,PN) которая возвращает код ошибки и  табельный номер и/или ID созданной записи. А уж потом для этой хранимой процедуры можно создать обертку в виде класса. Это мой личный подход.


Виталий Панасенко   (2006-09-25 14:32:00) [4]


> ...А из триггера айдишничек-то не вернешь...
> Ну, впрочем, это давнишний холивар, больше не буду  :)

В ЖарПтице 2 с использоваением FIBPLus - аж бегом ! (ФИБы поддерживают эту возможность "двойки")


Val   (2006-09-25 14:21:00) [5]

>А как же "бизнес-логика на сервере"?...
Вроде как от данного подхода не страдает, даже наоборот, многое, что должно/может сопутствовать вставке в данную табличку, можно красиво зашить в данную хп, получая неделимый для выполнения/отката блок.
...А из триггера айдишничек-то не вернешь...
Ну, впрочем, это давнишний холивар, больше не буду  :)


Виталий Панасенко   (2006-09-25 14:10:00) [6]


> dr Gonzo ©   (25.09.06 13:33) [11]
> Правильнее сразу в теле процедуры на вставку получать новоре
> значение генератора (в переменную), записывать его в поле
> ID и его же возвращать в RETURN_VALUES. Чем использование
> тригера.

А как же "бизнес-логика на сервере"? тригер срабатывает на событие, генерируемой системой (БД). А ХП придется вызывать из приложения.. или опять же - из тригера...


dr Gonzo   (2006-09-25 13:47:00) [7]

Я лично приверженец того, чтобы Insert Update таблиц был только через хранимые процедуры. При таком подходе в принципе удобнее всего получение ID вставлять как раз в хранимую процедуру на Insert объекта. Хотя можно продублировать и в тригере :)


Sergey13   (2006-09-25 13:42:00) [8]

> [11] dr Gonzo ©   (25.09.06 13:33)

Почему не правильнее это делать в клиенте?
Тригер срабатывает всегда, а ХП только когда ее вызовут. Улавливаешь разницу?


dr Gonzo   (2006-09-25 13:33:00) [9]

Правильнее сразу в теле процедуры на вставку получать новоре значение генератора (в переменную), записывать его в поле ID и его же возвращать в RETURN_VALUES. Чем использование тригера.


Sergey13   (2006-09-25 12:52:00) [10]

> [8] dr Gonzo ©   (25.09.06 12:18)

Правильнее чем что? И в чем принципиальная разница? И что даст отказ от тригера?


Виталий Панасенко   (2006-09-25 12:44:00) [11]


> dr Gonzo ©   (25.09.06 12:02) [6]
> X = GEN_ID(G_Table_1, 0);
>
> Обычно применяется в транзакции, сразу после вставки, для
> возвращения ID только что созданной записи. Если есть еще
> способы прошу поделиться.

FireBird 2.0+FIBPLus


dr Gonzo   (2006-09-25 12:18:00) [12]

тогда правильнее создавать сразу процедуру на вставку, без использования тригера - это если нужно потом получать только что вставленное значение ID.


Sergey13   (2006-09-25 12:04:00) [13]

> [6] dr Gonzo ©   (25.09.06 12:02)
> Обычно применяется в транзакции, сразу после вставки, для
> возвращения ID только что созданной записи. Если есть еще
> способы прошу поделиться.

Генератор работает ВНЕ контекста транзакции. Поэтому надо получать значение не ПОСЛЕ вставки, а ДО нее, и использовать далее полученное значение.


dr Gonzo   (2006-09-25 12:02:00) [14]

X = GEN_ID(G_Table_1, 0);

Обычно применяется в транзакции, сразу после вставки, для возвращения ID только что созданной записи. Если есть еще способы прошу поделиться.


Sergey13   (2006-09-25 11:18:00) [15]

> [4] dr Gonzo ©   (25.09.06 11:14)

> 3. Если нужно получить значение только что сгенерированного
> значения
> генератора то используем:
>
> X = GEN_ID(G_Table_1, 0);

Теоретически можно нарваться на неприятности.


dr Gonzo   (2006-09-25 11:14:00) [16]

0. Таблица допустим  

Table_1 ( PkId   INT, Field1  INT)
1. Должен присутствовать генератор:

Например создать генератор G_Table_1

2. Присваиваем значение генератора в тригере перед Insert'oм :

CREATE TRIGGER Table_1_BeforePost FOR Table_1
ACTIVE BEFORE INSERT POSITION 0
AS
begin
 IF (NEW.PkId IS NULL) THEN
   NEW.PkId =  GEN_ID(G_Table_1, 1);
end


3. Если нужно получить значение только что сгенерированного значения
генератора то используем:

X = GEN_ID(G_Table_1, 0);


Desdechado   (2006-09-23 18:04:00) [17]

повторю - читать ibase.ru

исключение может давать Д, тогда сделай поле в настройках компонентов необязательным или же заполняй его нулем, например
и триггер ACTIVE

и думать больше


Sinus   (2006-09-23 17:46:00) [18]

Генератор уже привязан к поля таблицы  ...
-(


Desdechado   (2006-09-23 17:39:00) [19]

читать ibase.ru

ЗЫ генератор - сама по себе сущность
привязка генератора к полю таблицы выполняется триггером, например, BEFORE INSERT


Наверх

Титульная страница Поиск, карта сайта Написать письмо