[SQL - Oracle] Vypnutie integritneho obmedzenia

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod srobowak 9. 5. 2010 12:01

Mam 2 tabulky : "pracovnici" s atributom "zariadenie (FK)" , ktory odkazuje na tabulku "zariadenia" a urcuje zariadenie, na ktorom dany pracovnik pracuje. Ale v tabulke "zariadenia" mam atribut "zodpovedny (FK)" ktory odkazuje na tabulku "pracovnici" a urcuje, ktory pracovnik je zodpovedny za dane zariadenia.

Ide o to, ze ked mam prazdnu databazu a chcem vlozit noveho pracovnika, tak nemozem, lebo mu musim priradit zariadenie (ale tabulka zariadenia je este prazdna). A naopak, ked chcem pridat zariadenie, tak nemozem, lebo mu musim pridat zodpovedneho pracovnika.

Preto by som potreboval docasne vypnut kontrolu integrity, ale neviem presne ako sa to robi (zrejme cez disable constraint alebo tak).
srobowak
Junior

Odeslat příspěvekod Nargon 9. 5. 2010 13:53

Imho takovyto navrh databaze je celkem spatny. Mit dve tabulky, kde jedna odkazuje na druhou a zase zpet neni nejlepsi zpusob reseni.

Ale zkusil bych pouzit transakce. Mozna kdyz v jedne transakci vytvoris zaznam v obou tabulkach a vzajemne je prekrizis, tak to bude fungovat. Ale moc bych na to nespolehal.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod gandor 9. 5. 2010 15:07

Mne sa ten navrh tiez nepozdava, ale keby som uz za kazdu cenu musel nieco taketo riesit, tak ani by som si nic nezistoval a netrapil sa s kontrolu integrity, ale nasurovku docasne zrusil jeden foreign key (co brani pridaniu ho az po naplneni jednej tabulky datami? ) .....
gandor
Mírně pokročilý

Odeslat příspěvekod JanFiala 9. 5. 2010 15:21

Pak mas spatne navrzenou databazi. Integritni musis nastavit na jednostranne, to znamena, ze ti nebude branit naplnit zakladni ciselniky, ale naopak bude hlidat zaznam v ciselniku, ktery uz je pouzity.

Mas tabulku pracovnici
Mas tabulku zarizeni
mas tabulku zodpovednost - vazba mezi pracovnikem a zarizenim. A jen na teto jedine tabuůlce ma smysl mit nastavenou integritu od pracovniku a od zarizeni.
Co můžeš udělat dnes, odlož na včerejšek
JanFiala
Expert
Uživatelský avatar

Odeslat příspěvekod Husqvik 6. 8. 2015 13:59

Oracle podporuje cyklické cizí klíče pomocí DEFERRED CONSTRAINTS, kdy se validace omezení odkládá na COMMIT.

Kód: Vybrat vše
CREATE TABLE pracovnici (
   id NUMBER PRIMARY KEY,
   zarizeni_id NUMBER
);

CREATE TABLE zariadenia (
   id NUMBER PRIMARY KEY,
   zodpovedny_pracovnik_id NUMBER CONSTRAINT fk_zariadenia_pracovnici REFERENCES pracovnici(id) DEFERRABLE INITIALLY DEFERRED
);

ALTER TABLE pracovnici ADD CONSTRAINT fk_pracovnici_zarizenia FOREIGN KEY (zarizeni_id) REFERENCES zariadenia(id);

INSERT INTO zariadenia VALUES (1, 1);
INSERT INTO pracovnici VALUES (1, 1);
COMMIT;


V tomto případě jeden z klíčů musí byt DEFERRED vždy. Existují případy kdy je odložené omezení potřeba jen výjimečně v tom případě by mělo být definováno jako INITIALLY IMMEDIATE. V rámci session se pak dá nastavit na DEFERRED pomocí

Kód: Vybrat vše
SET CONSTRAINTS fk_zariadenia_pracovnici DEFERRED


Rozhodně doporučuju si před použitím tuto problematiku nastudovat, protože odložená omezení přináši nemálo neočekáváných překvapení, např. non-unique indexy pro vynucení unikátnosti záznamu, nemožnost použití "table elimination" optimizace nebo dodatečná paměťová režie, zvláště při větších transakcích. Rozhodně automaticky nevytvářejte omezení jako DEFERRABLE.
Husqvik
Junior

Odeslat příspěvekod Vebloud 27. 8. 2015 15:37

Návrh databáze je zcela v pořádku. I když povinné pole zařízení je možná nevhodné, co když bude aplikace sloužit i k evidenci jiného druhu pracovníků, kteří nepracují na zařízeních. Taky bych se zamyslel nad tím, jestli pracovník nemůže pracovat na více zařízeních a na více zařízeních pracovat více pracovníků, například ve více směnách.

Ale to už se pohybuji v oblasti business požadavků, ne vyřešení současného problému, ten nicméně velice pěkně popsal Husqvik.

Nicméně pro první naplnění databáze nebo velké importy je dobré si constrainty dočasně vypnout a c případě, že při zapnutí ti to padne na constraint violation, tak musíš celý import rollbacknout. Nicméně takové cvičení není vhodné dělat na běžící aplikaci.

http://stackoverflow.com/questions/1286 ... -in-oracle
Žít a nechat žít, ty máš svůj názor, já mám svůj názor, já ti nebudu nutit svůj, nemusím souhlasit s tvým, ale udělám vše, abys ho mohl svobodně vyjádřit.
Vebloud
VIP uživatel
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků