Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

provjera i kopiranje podataka u store proceduri

[es] :: Firebird/Interbase :: provjera i kopiranje podataka u store proceduri

[ Pregleda: 2316 | Odgovora: 13 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

FranjoZG
Franjo Popović
Programer
Zagreb

Član broj: 328819
Poruke: 298
*.cust.tele2.hr.



+4 Profil

icon provjera i kopiranje podataka u store proceduri29.12.2018. u 20:08 - pre 63 meseci
Radim na FB 2.5 novu app i traže potpuni history izmjena podataka u bazi. Nije neki problem osim što je puno pisanja u trigerima
Zanima me da li se može napraviti nešto poput:
Code:

for i := 0 to Tablica.FieldCount-1
  if (New.Tablica.Field[i] <> Old.Tablica.Field[i]) then
     isnert into history(FieldName, OldValue) values(Tablica.Field[i].Name, Old.Tablica.Field[i]);


nadam se da je jasno o čemu se radi, želio bih izbjeći pisanje hrpe linija koda jer neke tablice imaju i 50-tak field-ova.
Kod bih stavio u trigere BeforeUpdate i BeforeDelete. Ako ne, ne preostaje mi nego (nažalos) za svaki field pisati:
Code:

if ((new.Field1 <> old.Field1) or ((new.Field1 is null) and (old.Field1 is not null)) or ((new.Field1 is not null) and (old.Field1 is null)) then
   insert into history(FieldName, OldValue) values('Field1', old.Field1);


(da sam volio puno pisati nikad ne bih postao programer...)
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Re: provjera i kopiranje podataka u store proceduri29.12.2018. u 20:25 - pre 63 meseci
Ne znam direktan odgovor, ali ako ne budes mogao bas tako kako si zamislio, mozes napisati kod poput tog prvog koji ce ti generisati sql skriptu koju ne zelis da pises rucno :)
 
Odgovor na temu

FranjoZG
Franjo Popović
Programer
Zagreb

Član broj: 328819
Poruke: 298
*.cust.tele2.hr.



+4 Profil

icon Re: provjera i kopiranje podataka u store proceduri29.12.2018. u 20:49 - pre 63 meseci
Tako sam i mislio... našao sam EXECUTE STATEMENT, samo što mi javlja grešku ako string počinje sa "If" ili "Case"
Nešto kao:
Code:

  for select rdb$field_name, '(case when (new.' || rdb$field_name || ' is distinct from old.' || rdb$field_name || ') then Pomi = 1 else Pomi = 0)'
  from rdb$relation_fields
  where rdb$relation_name = 'DJELATNICI' into :PomF, :poms do begin
     execute statement PomS;


Kada dobijem pomi, lako je kasnije.... pokušat ću sa kastanjem svih old. i new. field-ova pa njihovom usporedbom...
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3445

Jabber: djoka_l


+1462 Profil

icon Re: provjera i kopiranje podataka u store proceduri29.12.2018. u 23:04 - pre 63 meseci
Franjo, čini mi se da potpuno pogrešno postavljaš problem, možda grešim.

Ako izmeniš slog u bazi jednom komandom, to može da izmeni više polja. Iz ovoga kako si napisao nikako ne može da se zaključi ni ko je, ni kada, ni šta sve izmenio.
Generalno, problem može da se reši na više načina.

1. Svaka tabela može da se dopuni poljima, na primer, VERZIJA, DATUM_UNOSA. Ideja je da insert napravi verziju 1, a da svaki update napravi insert kompletnog sloga sa verzijom uvećanom za jedan. Ovo je recimo princip kod pravljena DWH. Delete je praktično neverovatno. Večina aplikacija malo toga briše iz baze, osim ako su to neki privremeni podaci. Upiti bi bili malo komplikovaniji, jer bi trebalo da se traži max verzije, ali nije neizvodljivo.
2. Drugi pristup bi bio da se u momentu kada se radi update, slog prekopira u arhivsku tabelu, pa da se tek onda radi update. Arhivska tabela bi trebala da ima PK koji nije isti kao PK iz radne tabele nego ima dodato polje verzija ili datum u PK.
3. Treći pristup bi bio da se, umesto da se radi update ili insert sloga u arhivsku tabelu, formira, na primer, JSON podatak koji opisuje transakciju, pa da se JSON arhivira i da se istorija izmena prati kroz neku nosql bazu.
 
Odgovor na temu

FranjoZG
Franjo Popović
Programer
Zagreb

Član broj: 328819
Poruke: 298
*.cust.tele2.hr.



+4 Profil

icon Re: provjera i kopiranje podataka u store proceduri30.12.2018. u 11:26 - pre 63 meseci
djoka_i, ovo je bio samo primjer, normalno da pamtim i tko je mijenjao i kada neki podatak. Nisam mislio raditi kopiju cijelog sloga neke tablice već samo field-ova koji su mijenjani (manje podataka, manja baza...). To sam napravio u nekim projektima i radi odlično.
Pitanje je bilo: kako to napraviti dinamički, tj. kako izbjeći pisanje provjere i upisa za svaki field?
Koliko sam gledao po net-u, moglo bi se sa EXECUTE STATEMENT kome se pošalje formirani string, ali tu se ne može koristiti IF ili CASE. Pokušao sam sam "Select Old.Fiel1, New.Field1 from RDB$DATABSE", ali tu ne priznaje Old i NEw (govorim o trigeru). Zanima me kako izbjeći pisanje silnih provjera u trigeru, za svaki field, npr:
Code:

if ((new.Field1 <> old.Field1) or ((new.Field1 is null) and (old.Field1 is not null)) or ((new.Field1 is not null) and (old.Field1 is null)) then
   insert into history(TableName, FieldName, OldValue, User, DatVri) values('Tablica1', 'Field1', old.Field1, current_user, current_timestamp);


U samom kodu programa, na formi, znam koji je podatak iz koje tablice i koji field, pa nije teško prikazati history za svaki od njih.

Poslije san našao i nešto kraći način:
Code:

if (new.Field1 is distinct from old.File1) then
   ...
 
Odgovor na temu

savkic
Igor Savkić

Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: provjera i kopiranje podataka u store proceduri30.12.2018. u 11:50 - pre 63 meseci
Jedino da dinamicki generises triggere, tipa krenes za svaku tabelu u bazi, procitas koja polja ima, napises kod za poredjenje i dalje smestanje u history tabelu. BTW nemoj smestati slog u history za svaku promenu polja vec ubaci sve promene za taj u jedan history slog.
 
Odgovor na temu

FranjoZG
Franjo Popović
Programer
Zagreb

Član broj: 328819
Poruke: 298
*.cust.tele2.hr.



+4 Profil

icon Re: provjera i kopiranje podataka u store proceduri30.12.2018. u 18:34 - pre 63 meseci
savkic, kako misliš? da kopiram cijeli slog umjesto field-a? Kopija sloga prije izmjene?

... koji smo mi bolesnici... nedjelja, a mi na forumu, programiramo, umjesto van sa ženom, djecom, ljubavnicom, prijateljima...
 
Odgovor na temu

savkic
Igor Savkić

Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: provjera i kopiranje podataka u store proceduri30.12.2018. u 19:41 - pre 63 meseci
> savkic, kako misliš? da kopiram cijeli slog umjesto field-a? Kopija sloga prije izmjene?

Mozes i tako ali tu onda moras da pravis neku serijalizaciju tog sloga, mislio sam da samo listujes promenjena polja tipa:
Changes for fields:
FieldA; StaraVrednost->NovaVrednost
FieldB; StaraVrednost2>NovaVrednost2
...

> ... koji smo mi bolesnici... nedjelja, a mi na forumu, programiramo, umjesto van sa ženom, djecom, ljubavnicom, prijateljima...

A pa pivo cemo sutra a zenu kasnije ;)
 
Odgovor na temu

schild
Dejan Šild
TopCode Software
Subotica

Član broj: 59888
Poruke: 138
*.opera-mini.net.

Sajt: www.topcode.rs


+2 Profil

icon Re: provjera i kopiranje podataka u store proceduri30.12.2018. u 19:46 - pre 63 meseci
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.
 
Odgovor na temu

FranjoZG
Franjo Popović
Programer
Zagreb

Član broj: 328819
Poruke: 298
*.cust.tele2.hr.



+4 Profil

icon Re: provjera i kopiranje podataka u store proceduri01.01.2019. u 15:09 - pre 63 meseci
shild, mislim da ću ići na taj način kako si napisao, prelijen sam da pišem za svaku tablicu triger, nego kreirat ću ga iz programa.
Kad se program starta, provjerim strukturu tablica, pa ako sa mijenjala - rekreiram triger, tako da više ne mislim na to (i ne zaboravim...)

Nisam gledao FB3, da li je tu što mijenjano.
 
Odgovor na temu

FranjoZG
Franjo Popović
Programer
Zagreb

Član broj: 328819
Poruke: 298
93.140.4.*



+4 Profil

icon Re: provjera i kopiranje podataka u store proceduri03.01.2019. u 09:05 - pre 63 meseci
schild, napravio sam kako si mi dao ideju, odlično!
- pri pokretanju programa napravim execute procedure u bazi, a ona napravi:
- provjeri da li postoji trigger afterupdate
- provjeri u pomoćnoj tablici s field-ovima: table_name i field_name da li su upisani svi fieldovi tablice koju provjeravam
- ako ne postoji trigger ili u tablici koju provjeravam postoji field koji nije upisan u pomoćnu tablicu - rekreiram triger

Na taj način više ne moram misliti o trigeru niti nakon izmjene strukutre tablice niti kod dodavanja nove tablice, kreira se automatski. Jedino još razmišljam ako mi treba afterupdate za nešto drugo, možda u pomoćnu tablicu u blob upisati što treba dodati...
 
Odgovor na temu

schild
Dejan Šild
TopCode Software
Subotica

Član broj: 59888
Poruke: 138
*.dynamic.isp.telekom.rs.

Sajt: www.topcode.rs


+2 Profil

icon Re: provjera i kopiranje podataka u store proceduri03.01.2019. u 09:23 - pre 63 meseci
Drago mi je da si uspeo! Ako ne menjaš strukturu baze često, onda možda i ne moraš tu proceduru uvek pozivati, nego samo kad radiš update. Tj. ne bi je ni trebao pozivati ako imaš drugih korisnika koji su konektovani na bazu, jer promena strukture dok nisi jedini korisnik zna biti problematična.
Vezano za after trigere, njih možeš imati više, pa ne moraš brinuti da ćeš sa ovim tvojim log trigerom obrisati neki drugi (osim ako se baš isto tako zove).
Bitno oko after trigera: UVEK stavi da je ovaj tvoj triger na position 0, a svi ostali after trigeri da su pozicije veće od nule. To je za slučaj da u nekom trigeru menjaš nešto u nekoj drugoj tabeli, da onda log od te druge tabele ne bude pre loga od ove prve. Možda ti to i nije bitno, ali ako hoćeš da bude baš po redosledu izmena, onda obrati pažnju.

FB3 je potpuno kompatibilan sa FB25, tako da će raditi i na njemu. FB3 ima mnogo dobrih novina, ja u zadnje vreme većinu stvari koje sam radio kroz aplikaciju, sada programiram u stored procedurama, mnogo brže radi, a neki put mi je i lakše tako.
 
Odgovor na temu

FranjoZG
Franjo Popović
Programer
Zagreb

Član broj: 328819
Poruke: 298
93.140.4.*



+4 Profil

icon Re: provjera i kopiranje podataka u store proceduri03.01.2019. u 10:00 - pre 63 meseci
He, napravio sam kompletnu automatiku: kreiram pomoćnu tablicu ako ne postoji, dodajem u svaku tablicu fieldove: "izmjena_user" i "izmjena_datum_vrijeme" koji se pune kod afterupdate i afterinsert, kreirao i trigger afterdelete :)

Prije nešto vremena sam probao instalirati FB3 i nije mi radilo... ne sjećam se više u čemu je bio problem ali sam odustao od update-a na FB3. Možda su u međuvremenu nešto mijenjali.
Može li FB3 raditi sa bazama koje su za FB 1.5? Imam još klijenata koji su na FB 1.5, a zbog nekih programa (nisu moji) koji ne rade na FB 2.5 je kod njih još uvijek instaliran FB 1.5
 
Odgovor na temu

schild
Dejan Šild
TopCode Software
Subotica

Član broj: 59888
Poruke: 138
*.dynamic.isp.telekom.rs.

Sajt: www.topcode.rs


+2 Profil

icon Re: provjera i kopiranje podataka u store proceduri03.01.2019. u 10:14 - pre 63 meseci
FB3 je malo komplikovaniji za instalaciju, ima dosta nekih security opcija koje smaraju. Treba proučiti na netu šta su novine.
Ne može da radi sa starijim bazama, čak ni sa FB25, mora obavezno backup na starom FB, pa restore na trojci.
 
Odgovor na temu

[es] :: Firebird/Interbase :: provjera i kopiranje podataka u store proceduri

[ Pregleda: 2316 | Odgovora: 13 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.