Ja sam bio pravio da se kroz SP kreiraju trigeri za repplikaciju. Malo duža priča, ali ukratko dajem par smernica:
Upit koji lista podatke o poljima i tabelama, uz malo modifikacije može dati puno korisnih informacija:
Code:
select decode(F.RDB$FIELD_TYPE, 12, 'DATE', 14, 'CHAR', 16, 'NUMERIC', 35, 'TIMESTAMP', 37, 'VARCHAR', 7, 'SMALLINT', 8, 'INTEGER', 27, 'DOUBLE', 261, 'BLOB', F.RDB$FIELD_TYPE) as DATA_TYPE
from RDB$RELATIONS R
join RDB$RELATION_FIELDS RF on RF.RDB$RELATION_NAME = R.RDB$RELATION_NAME
left join RDB$FIELDS F on F.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE
where R.RDB$SYSTEM_FLAG = 0 and
trim(RF.RDB$RELATION_NAME) = :V_SRC_TABNAME and
trim(RF.RDB$FIELD_NAME) = :V_SRC_FLDNAME
Ovo dalje je delić procedure, koji kreira deo za upis:
Code:
-- ispred ide Recreate trigera itd, ovo je deo gde logujes promene po poljima..
V_TRIGGERNAME = PREFFIX || left(v_src_tabname,26) || SHID ||'U';
sqql='RECREATE TRIGGER '|| V_TRIGGERNAME ||' FOR '|| v_src_tabname ||' '||ascii_char(13)||ascii_char(10)||
'ACTIVE AFTER UPDATE POSITION '|| TRIG_POS ||ascii_char(13)||ascii_char(10)||
'AS '||ascii_char(13)||ascii_char(10)||
'declare variable RID bigint; '||ascii_char(13)||ascii_char(10)||
'begin '||ascii_char(13)||ascii_char(10);
-- tu ide petlja sa listom polja...
if ((V_DATA_TYPE<>'VARCHAR') and (V_DATA_TYPE<>'BLOB')) then
V_CAST_FIELD = 'cast(:' || v_src_fldname || ' as varchar(32))';
else V_CAST_FIELD = ':' || v_src_fldname;
sqql = sqql ||
' insert into repltc$log_values (rid, dest_fldname, is_key, old_value, new_value, is_blob)'||ascii_char(13)||ascii_char(10)||
' values (:rid, ''' || v_dest_fldname ||''', '|| is_key ||', '
|| REPLACE(V_CAST_FIELD,':','old.') ||', '
|| REPLACE(V_CAST_FIELD,':','new.') ||', '
|| iif(V_DATA_TYPE='BLOB', 1, 0) ||');'||ascii_char(13)||ascii_char(10)||
ascii_char(13)||ascii_char(10);
end
sqql = sqql || 'end';
execute statement :sqql;
Izvinjavam se što nisam ovo bolje prečistio i pripremio, ali mislim da ima dovoljno matrijala da shvatiš kako bi to mogao izvesti. Sve u svemu, vrlo izvodivo kroz jednu jedinu SP da uradiš trigere za sve tabele.
Mislim da je bolje da loguješ u AFTER trigerima nego u BEFORE. Možeš sve data tipove da castujes kao varchar(32), firebird će posle pravilno da konveruje unazad ako treba. Naravno ako je varchar veći od 32 ili je blob, onda moraš u posebno polje da loguješ, možda imati i blob polja.