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 Databases