Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.034 c
1-1082970081
HarryP
2004-04-26 13:01
2004.05.16
Unicode


14-1082757538
Petr. A. V
2004-04-24 01:58
2004.05.16
Freecell


9-1071270135
Legafor
2003-12-13 02:02
2004.05.16
2D Движок


4-1080239386
Константин
2004-03-25 21:29
2004.05.16
Как запустить из процесса другую программу?


14-1082889813
Nikolay M.
2004-04-25 14:43
2004.05.16
Крутится в голове песТня, а названия не помню :(





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский