2 // Tím říkáš, že každý byt může mít libovolný počet vlastníků.
Áno. Ber to v určitom časovom rozsahu. Jeden byt predá a iný ho kúpi.
V tom případě máš ale blbě master-detail vztah - Flats by měly být master a Landlords detail.
3 Citujem sa:
1 - Vyvolám Flats.Post. Vo Flats.onBeforePost získam newPrKey. Napríklad 10.
2 - Vložím ho do Landlords.FKFlat.
3 - Potom nasleduje Landlords.Post s chybou.
Takže záznam by už mal existovať.
Za prvé to záleží na tom, v jakém přesně pořadí ty Posty probíhají (jestli například doběhne celý Flats.Post a teprve potom začne Landlords.Post), a za druhé mám vážné podezření, že vyplňuješ špatná políčka (že si pomocí procedury vytáhneš ID, ale potom ho přepíšeš v triggeru, nebo že si vytáhneš ID, ale zapíšeš ho do jiného pole, než jaké je referencované tím cizím klíčem). Docela dobrá taktika v takových případech je, smazat cizí klíč, zkusit zapsat záznam (teď to proběhne, protože už není nic, co by ho mělo blokovat) a pak se podívat, co jsi kam skutečně zapsal po provedení všech triggerů.
a - Vyvolám FlatsDataSet.Post. Neviem ako sa to správa. Nikde som nenarazil na popis.
b - FB spustí trigger Flats Before Insert
c - Vo FlatsDataset.onBeforePost získam v procedúre FB hodnotu IDFlats uložením do newPrKey. Potiaľ to je v priadku.
d - Vložím ju do LandlordDataset.FKFlats := newPrKey;
e - Vyvolám LandlordDataset.Post s danou chybou.
Jinými slovy, v tuto chvíli jsi ještě ve stavu FlatsDataset.BeforePost. Skutečný zápis do DB proběhne až později a potom se ti zavolá FlatsDataset.AfterPost.
f - FB jednoznačne opäť vyvolá trigger Flats Before Insert. Tu je kameň úrazu. Prečo ho spustí, ak
. 1 - už raz spustený bol pomocou DataSet-u
. 2 - hodnotu pre FKFlats som tam dal?
Trigger se spouští v databázi. Databáze neví nic o tom, co dělá nebo nedělá aplikace, a ani ji to nezajímá. Prostě se podívá: "Mám tu trigger pro aktuálně prováděnou událost? Ano. Je ten trigger aktivní? Ano. Tak ho spustím." Je tvoje zodpovědnost, abys trigger napsal tak, aby případně nic nědělal - tedy třeba na začátku provést nějaký vhodný IF a pokračovat, jen pokud operace ještě neproběhla.
Podle mě máš blbě datový model. Jak souvisí hodnota FKFlats (která je v tabulce Landlords) s triggerem na tabulce Flats? Trigger na tabulce Flats se má zabývat výhradně údaji v tabulce Flats, nemá co se zabývat cizími klíči cizích tabulek.
Ja potrebujem dosiahnuť, aby nedochádzalo k druhému spusteniu trigger-u Flats Before Insert
Jsem si stoprocentně jistý, že
nedochází k druhému spuštění Before Insert triggeru na Flats. Before Insert nastane právě jednou, a to v okamžiku, kdy databáze narazí na INSERT INTO tabulka. A to platí i v případě, že to INSERT INTO tabulka neděláš ty, ale dělají ho tvoje komponenty pro přístup k DB.
Takže špatně vyhodnocuješ, co se děje. Možností je víc, ale podle mě děláš jednu z následujících věcí:
a) Vygeneruješ hodnotu procedurou, tu si uložíš, zapíšeš ji do tabulky a pak ji v tabulce přepíšeš hodnotou vygenerovanou v triggeru - tzn. máš blbě podmínku v triggeru.
b) Vygeneruješ hodnotu procedurou, tu si uložíš, zapíšeš ji do tabulky do špatného sloupce a pak trigger pochopitelně vygeneruje novou hodnotu, protože podmínka "hodnota v poli X ještě nebyla vygenerována" je splněna.
Dost blbě se odhaduje, co z toho, protože jsi sice vypsal relevantní části kódu, ale už jsi nenapsal struktury jednotlivých tabulek a vztahy mezi nimi - asi nejlíp příslušný CREATE TABLE příkaz.
K poslednému odseku.
// Máš to mít tak, že v Landlords nemáš nic a ve Flats máš ukazatel na Landlords.
To nie je vhodné riešenie. Počas roka dôjde zmene vlastníka a ja ich musím mať k dispozícii oboch - ročné zúčtovanie nákladov.
V tom případě prosím dej jako Master tabulku Flats a jako Detail tabulku Landlords. A do všech popisků k tomuto problému zdůrazňuj, že mezi Flats a Landlords je vztah 1:N, protože jinak je to strašně matoucí - běžné bývá spíš to, že jeden majitel má víc bytů, ne že jeden byt má víc majitelů.
(Vůbec by možná bylo nejlepší udělat to jako M:N s tím, že spojovací tabulka bude mít ID bytu, ID vlastníka a období [datum od, datum do], pro které to platí.)
2. Toto si viem riešiť ako potrebujem. Aj vzťahom M:N. Ešte som to tak podrobne neanalyzoval. Hlavne to nemá vplyv na predmet otázky.
Má. Poměrně podstatný, aspoň podle mě je docela vhodné důkladně pochopit popisovanou realitu a z ní odvozovat řešení, než střílet různé myšlenky od boku a doufat, že se nějaká trefí.