Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.16;
Скачать: CL | DM;

Вниз

Связанные таблицы   Найти похожие ветки 

 
kalliopiy   (2004-04-21 17:21) [0]

Здравствуйте!

Подскажите как выйти из следующей ситуации. Есть две связанные таблицы, например, Организации (главная) и Подразделения (подчиненная). В БД создан внешний ключ для таблицы подразделений на таблицу организаций. При попытке внесения новой записи в таблицу организаций, а потом заполнения для этой организации ее подразделений, возникает ошибка violation of Foreign Key. Т.е. пока не сохранена запись с новой организацией нельзя внести для нее подразделения. Причем сохранена она должна быть не просто через Post, но еще и через Commit для соответствующей транзакции.

Возможно ли как-то сделать так, чтобы одновременно можно было бы вносить новую запись в главную таблицу, а потом несколько записей в подчиненную да еще и так, чтобы в случае отмены можно было бы сделать на все это общий откат (Rollback)?


 
Johnmen ©   (2004-04-21 17:24) [1]

>Причем сохранена она должна быть не просто через Post, но еще и
>через Commit для соответствующей транзакции.

После Post вставляй в подчинённую. А потом Commit/Rollback.


 
dimm22   (2004-04-21 17:25) [2]


> Возможно ли как-то сделать так, чтобы одновременно можно
> было бы вносить новую запись в главную таблицу, а потом
> несколько записей в подчиненную да еще и так, чтобы в случае
> отмены можно было бы сделать на все это общий откат (Rollback)?

С помощью триггеров.


 
kalliopiy   (2004-04-21 17:34) [3]


> После Post вставляй в подчинённую. А потом Commit/Rollback.


Я-то так и делаю. Т.е. примерно такой код в OnClick"e кнопки "Добавить подразделение"

if firmsDS.FieldByName("id").IsNull then firmsDS.Post;
divisionsDS.Append;
divisionsDS.FieldByName("firmID").AsInteger:=firmsDS.FieldByName("id").AsInteger;


Первый раз все проходит нормально и можно заполнять поля для Подразделения, но как только нажимаешь на эту кнопку еще раз, т.е. производится Post предыдущего Подразделения и попытка добавить новое (ну, вобщем-то до этого и не доходит, т.к. на Post-е уже облом), то сразу выдается вышеописанная ошибка.

Что ж делать-то?


 
Johnmen ©   (2004-04-21 17:39) [4]

Присваивать
divisionsDS.FieldByName("firmID").AsInteger
существующее значение из firmsDS


 
kalliopiy   (2004-04-21 17:45) [5]

:)) Так я же так и делаю! И даже в гриде видно, что id и firmID одинаковые, но ошибка все равно выдается

И Датасеты ведь под одной транзакцией работают, вроде же все правильно должно быть


 
Johnmen ©   (2004-04-21 17:53) [6]

>Так я же так и делаю! И даже в гриде видно, что id и firmID
>одинаковые, но ошибка все равно выдается

Лучше в этом убедиться при присваивании.


 
Соловьев ©   (2004-04-21 18:00) [7]


> Johnmen ©   (21.04.04 17:53) [6]

так как транзакция не подтверждена - то понятно то на уровне БД происходит исключение. Нужно сначала закомитить мастера, а потом только вносить данные в детайл


 
Johnmen ©   (2004-04-21 18:02) [8]

>Соловьев ©   (21.04.04 18:00) [7]

Ничего подобного.
:)


 
Соловьев ©   (2004-04-21 18:09) [9]


> Johnmen ©   (21.04.04 18:02) [8]

т.е. Вы хотите сказать, что получив на клиенте id мастера, но не внеся его в БД(commit) можно добавлять с таким же id в детайл?


 
Johnmen ©   (2004-04-21 18:12) [10]

>Соловьев ©   (21.04.04 18:09) [9]

Я хочу сказать, что стартовав тр-ию и добавив запись в мастера, можно сразу добавлять в деталь, не разделяя эти вставки коммитом/роллбеком...


 
kalliopiy   (2004-04-21 18:18) [11]

2 Johnmen

Я тоже думаю, что так не должно быть и кажется я понял где у меня подвох.

Дело в том, что для таблицы Организаций у меня в БД создан триггер, который автоинкрементирует поле id. Но вот в Делфи я для соответствующего Датасета сделал GeneratorField (указав этот самы триггер и поле, а инкремент 1) и теперь он в гриде мне показывает одно id, а в базу попадает по-моему значение на единицу меньше.

Так как тут лучше выкрутиться?


 
Johnmen ©   (2004-04-21 18:23) [12]

>kalliopiy   (21.04.04 18:18) [11]

Конечно ! Это ошибка. Выкинь из триггера манипуляции с генератором.
(Но я бы сделал идеологически по-другому)


 
kalliopiy   (2004-04-21 18:27) [13]


> Johnmen ©   (21.04.04 18:23) [12]


Так а как лучше сделать, подскажите пожалуйста, потому что мне важнее понять как сделать правильнее, чем просто исправить ошибку!

Кстати, если убрать из триггера манипуляции с генератором, то получится, что он будет пустой (т.е. ничего делать не будет)


 
Соловьев ©   (2004-04-21 18:30) [14]


> Дело в том, что для таблицы Организаций у меня в БД создан
> триггер, который автоинкрементирует поле id.

должна быть обязательно проверка
if(New.Id is NULL)then New.Id = Gen_id(gen_name, 1);


 
kalliopiy   (2004-04-21 18:33) [15]


> Соловьев ©   (21.04.04 18:30) [14]


Есть такая проверка, а как же :))!


 
Johnmen ©   (2004-04-22 09:13) [16]

>kalliopiy   (21.04.04 18:27) [13]
>Так а как лучше сделать,...

Я думаю лучше сначала получить очередное значение генератора, а потом его использовать в приложении. Получить можно запросом, можно с помощью ХП, можно неявно, указав в необходимые значения в AutoUpdateOptions DataSet"а (FIB+).


 
фыва   (2004-04-22 10:23) [17]

Мне кажется, надо просто написать хранимую процедуру. Все описанные действия реализуются в ХП.
Работать с SQL сервером через TTable - это переносить логику xBase & Paradox, т.е. файл-серверных платформ на SQL, что не есть правильно. Вообще-то, бизнес логика приложения на SQL платформе должна танцевать от запросов и хранимых процедур а не TTablов.


 
Johnmen ©   (2004-04-22 10:30) [18]

Казалось бы, причём здесь TTable ?
:)


 
Sergey13 ©   (2004-04-22 11:00) [19]

2kalliopiy
Поставь перед
divisionsDS.Append;
showmessage или отладчиком посмотри firmsDS.FieldByName("id").
Может ошибка где то в другом месте кода если один раз проходит, а другой нет.

2Johnmen ©   (22.04.04 10:30) [18]
>Казалось бы, причём здесь TTable ?
>:)
Зато как мощно задвинул. Особенно про SQL платформу. 8-)



Страницы: 1 вся ветка

Текущий архив: 2004.05.16;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.056 c
1-1083670457
Alkmas
2004-05-04 15:34
2004.05.16
FindClass из DLL


1-1083141363
Tsvetkov A.V.
2004-04-28 12:36
2004.05.16
Потоки в ДЛЛ


1-1083548734
Marat_D
2004-05-03 05:45
2004.05.16
Проблема с дельфой!!!


9-1072167927
Kair
2003-12-23 11:25
2004.05.16
Динамический массив


4-1079949095
dr Tr0jan
2004-03-22 12:51
2004.05.16
Элемент меню по умолчанию