Postgres 7.1.3, PL/pgSQL, trigger - rozbor
Karel Zak
zakkr na zf.jcu.cz
Středa Říjen 23 15:17:31 CEST 2002
On Wed, Oct 23, 2002 at 02:43:07PM +0200, otakarek na post.cz wrote:
> Mam tabulky: tab_A,tab_B,tab_C a tab_T, trigger tr_A
>
> Potrebuji si univerzalnim triggerem(tr_A) zajistit referencni
> integritu konkretniho sloupce(napr. tab_T.sl_A) do vice
> tabulek(tab_A,tab_B,tab_C) i do tabulky samotne(tab_T) pro potreby
> rekurze(nad tab_T).
Asi prvni logicka otazka: proc nepouzit normalni cizi klice z
PostgreSQL? REFERENCES muze ukazovat do stejne tabulky a ON DELETE
CASCADE vam zajisti odmazani pripadnych potomku (pokud je to strom).
> Diky pomocnemu sloupci(tab_T.sl_N) a prislusneho trigeru(tr_A) mam
> sestaveny sloupec, ktery obsahuje rekurzivni strom oddelenych
> identifikatoru za sebou (predpoklada se omezeny pocet "zanoreni").
>
> Az do ted nemam zadny problem. Pokud ovsem chci zajistovat integritu
> nad tab_T.sl_A, musi se to tykat i akci ON DELETE. Z vykonostnich
> duvodu chci v triggeru tr_A pouzit jen jeden SQL DELETE nad
> tab_T.sl_N. V tomto bode potrebuji docasne "zakazat" volani akci ON
> DELETE na tab_T (bohuzel DELETE nad tab_T.sl_N maze vice zaznamu a
> nezadoucne vyvolava onen tr_A).
Vestavena RI pouziva take triggery, ale pochopitelne je to
DELETE FROM ONLY <fktable> WHERE fkatt1 = $1 [AND ...]
(citovano ze zdrojaku), tedy v pripade, ze je to tabulka kde zaznamy
maji stromovou strukturu tak se rekurzivne vola stejny trigger pro
pripadne potomky (IMHO tento vestaveny trigger bude rychlejsi nez to
same v PL/SQL)
Pokud to chcete zvladnout jednim dotazem znamenalo by to v tom DELETE
vyjmenovat vsechna ID pro ktera se ma provadet mazani, neco jako:
DELETE <fktable> WHERE fkatt IN (id1, id2, ...)
coz je ale i tak nanic protoze o zpusobu jak podminene volat trigger
nevim (jedine, ze by to nejak poznal sam trigger)
> Nakonec tr_A provede sumarni operace a ulozi je do specialni tmp
> tabulky(nad tab_T).
>
> Ta predstava rekurzivniho volani(resp. mazani a sumarizovani) nad
> treba 1000 radky me deprimuje. RULE by na to stacila, ale co ty
> sumarni operace, ktere chci na zaver operaci nad tab_T provest? Mam
> pouzit interni "semafory" v ramci triggeru tr_A?
PostgreSQL neni multithread takze muzete v pripade, ze to napisete
treba v C pouzit nejakou statiskou promennou, ktera bude znacit, ze
se nemaji rekurzivne volat DELETE, ale je to reseni na... Osobne bych
sel cestou dvou dotazu
1/ summarizace
2/ mazat a pouzivat normalni RI s ON DELETE CASCADE
Karel
--
Karel Zak <zakkr na zf.jcu.cz>
http://home.zf.jcu.cz/~zakkr/
C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz
Další informace o konferenci Test