Ciao ragazzi, stò realizzando una libreria che permette di mettere in una tabella tutte le insert, gli update e le delete di un database firebird per ottenere un sistema di sincronizzazione.
Ci sono quasi, quello che mi manca è avere una funzione che mi dica se mettere gli apici nella query (perchè è una query che ricostruisco in base ai campi e alla tipologia). Avete idee al riguardo?
strTrig:='CREATE TRIGGER ' + Get_Identificativi_Trigger_Sync + '_' + NomeTabella + '_Ins_Upd FOR ' + NomeTabella + ' ' +
'AFTER INSERT OR UPDATE ' +
'AS BEGIN ' +
'IF (INSERTING) THEN ' +
'begin ' +
'insert into T_LOG (DATE_SQL, STRING_SQL) values ( current_timestamp, 'insert into TAB1(campo1,campo2,campo3)values('||New.CAMPO1||','''||New.CAMPO2||''','''||New.CAMPO3||''');'); ' +
'end else ' +
'begin ' +
'insert into T_LOG (DATE_SQL, STRING_SQL) values ( current_timestamp, 'update da aggiornare'); '+
'end '+
'END ';
Alla fine vado a creare un trigger per ogni tabella e dove vedete le due insert andrò a modificarle a run time andando a leggere il nome del campo e il tipo di campo dall'opportuna tabella di sistema.
Io userei "Format" per non incasinarmi la vita..... ;)
Format(
'Create trigger %s_%s_Ins_Upd for %1:s after insert or update as begin '+
'if (inserting) then '+
'begin ' .... [Get_Identificativi_Trigger_Sync,NomeTabella,...]);
Stilgar
Io userei "Format" per non incasinarmi la vita..... ;)
Format(
'Create trigger %s_%s_Ins_Upd for %1:s after insert or update as begin '+
'if (inserting) then '+
'begin ' .... [Get_Identificativi_Trigger_Sync,NomeTabella,...]);
Stilgar
Suggerimento apprezzato ma il mio problema è un altro.
Se vado a realizzare una query a runtime (all'interno del trigger costruito a run time) come faccio a sapere se il campo1 necessita di essere tra '?
Ad esempio
insert into tabella(campo1,campo2,campo3)values('0','caio','2');
come faccio a sapere che 0 deve essere inserito tra '0' e non come 0? Io ricerco una metodologia che funzioni senza doverci rimettere le mani sopra. Faccio un esempio con la seguente query
select CAMPI.RDB$FIELD_NAME, TipiDatiFirebird.RDB$TYPE_NAME
from
(select RDB$RELATION_FIELDS.RDB$FIELD_NAME, RDB$FIELDS.RDB$FIELD_TYPE from RDB$RELATION_FIELDS INNER join RDB$FIELDS ON RDB$FIELDS.RDB$FIELD_NAME=RDB$RELATION_FIELDS.RDB$FIELD_SOURCE where RDB$RELATION_NAME='T_LOG') as CAMPI
inner join
(select RDB$TYPE, RDB$TYPE_NAME from RDB$TYPES where RDB$FIELD_NAME='RDB$FIELD_TYPE') as TipiDatiFirebird
ON CAMPI.RDB$FIELD_TYPE=TipiDatiFirebird.RDB$TYPE
Ottengo la lista dei campi della tabella T_LOG e il relativo tipo. COme faccio a sapere in base al tipo di dato qual'è il separatore giusto?
Lazarus.
formatString := ''
for indice := 0 to numeroDiCampi do
begin
case capo[indice].typeOf do
'Stringa' :
begin
formatString := formatString + '\'%s\'';
parametro[indice] := campo[indice].value;
end;
....
end;
QuestyString := Format(formatString,campi);
Qualche cosa di simile....
Ragazzi, qualche passo avanti, provate a compilare l'esempio allegato, il database firebird è sempre allegato (pippo.fdb). Lanciate l'eseguibile premete il primo tasto, poi eseguite le seguenti query tramite flamerobin
insert into TAB2 (CAMPO1, CAMPO2, CAMPO3, CAMPO4)values (1,'CAMPO1',0,'CAMPO1');
insert into TAB2 (CAMPO1, CAMPO2, CAMPO3, CAMPO4)values (2,'CAMPO2',0,'CAMPO2');
insert into TAB2 (CAMPO1, CAMPO2, CAMPO3, CAMPO4)values (3,'CAMPO3',0,'CAMPO3');
insert into TAB2 (CAMPO1, CAMPO2, CAMPO3, CAMPO4)values (4,'CAMPO4',0,'CAMPO4');
update TAB2 set campo2='pippo', campo4='pippo', campo3=2 where campo1=1 and campo3=0;
delete from tab2 where campo1=1 and campo3=0;
Poi dall'eseguibile premete anche il secondo tasto. Dopo andate a vedere il file TLog.SQL, che dovrebbe risultare così
insert into TAB2(CAMPO1, CAMPO2, CAMPO3, CAMPO4)values(1, 'CAMPO1', 0, 'CAMPO1');
insert into TAB2(CAMPO1, CAMPO2, CAMPO3, CAMPO4)values(2, 'CAMPO2', 0, 'CAMPO2');
insert into TAB2(CAMPO1, CAMPO2, CAMPO3, CAMPO4)values(3, 'CAMPO3', 0, 'CAMPO3');
insert into TAB2(CAMPO1, CAMPO2, CAMPO3, CAMPO4)values(4, 'CAMPO4', 0, 'CAMPO4');
UPDATE TAB2 SET CAMPO2='pippo' WHERE CAMPO1=1 AND CAMPO2='CAMPO1' AND CAMPO3=0;
UPDATE TAB2 SET CAMPO3=2 WHERE CAMPO1=1 AND CAMPO2='CAMPO1' AND CAMPO3=0;
UPDATE TAB2 SET CAMPO4='pippo' WHERE CAMPO1=1 AND CAMPO2='CAMPO1' AND CAMPO3=0;
Il mio problema ora è che se vado a ricostruire il database con il risultato ottenuto, viene sbagliato, perchè:
UPDATE TAB2 SET CAMPO3=2 WHERE CAMPO1=1 AND CAMPO2='CAMPO1' AND CAMPO3=0;
cambia la chiave primaria per la query successiva
UPDATE TAB2 SET CAMPO4='pippo' WHERE CAMPO1=1 AND CAMPO2='CAMPO1' AND CAMPO3=0;
Come fare?
se non ho capito male, a fronte di una unica UPDATE, generi 3 UPDATE, una per ogni campo.
Tra l'altro nella where ci metti anche il vecchio valore.
Come mai non generi una sola istruzione?
Tu dici di far diventare (ad esempio) questo
SET TERM ^
ALTER TRIGGER TRIG_SYNC__TAB1_INS_UPD ACTIVE
AFTER INSERT OR UPDATE POSITION 0
AS BEGIN
IF (INSERTING) THEN
begin
insert into T_LOG (stato_record,DATE_SQL, STRING_SQL) values (0, current_timestamp, 'insert into TAB1(CAMPO1, CAMPO2, CAMPO3)values('||New.CAMPO1||', '''||New.CAMPO2||''', '''||New.CAMPO3||''');');
end else IF (UPDATING) THEN
begin
IF (New.CAMPO1<>Old.CAMPO1) THEN
BEGIN
insert into T_LOG (stato_record,DATE_SQL, STRING_SQL) values (0, current_timestamp, 'UPDATE TAB1 SET CAMPO1='||New.CAMPO1||' WHERE CAMPO1='||Old.CAMPO1||';');
END
IF (New.CAMPO2<>Old.CAMPO2) THEN
BEGIN
insert into T_LOG (stato_record,DATE_SQL, STRING_SQL) values (0, current_timestamp, 'UPDATE TAB1 SET CAMPO2='''||New.CAMPO2||''' WHERE CAMPO1='||Old.CAMPO1||';');
END
IF (New.CAMPO3<>Old.CAMPO3) THEN
BEGIN
insert into T_LOG (stato_record,DATE_SQL, STRING_SQL) values (0, current_timestamp, 'UPDATE TAB1 SET CAMPO3='''||New.CAMPO3||''' WHERE CAMPO1='||Old.CAMPO1||';');
END
end
END ^
SET TERM ; ^
In questo?
SET TERM ^
ALTER TRIGGER TRIG_SYNC__TAB1_INS_UPD ACTIVE
AFTER INSERT OR UPDATE POSITION 0
AS BEGIN
IF (INSERTING) THEN
begin
insert into T_LOG (stato_record,DATE_SQL, STRING_SQL) values (0, current_timestamp, 'insert into TAB1(CAMPO1, CAMPO2, CAMPO3)values('||New.CAMPO1||', '''||New.CAMPO2||''', '''||New.CAMPO3||''');');
end else IF (UPDATING) THEN
begin
insert into T_LOG (stato_record,DATE_SQL, STRING_SQL) values (0, current_timestamp, 'UPDATE TAB1 SET CAMPO1='||New.CAMPO1||',CAMPO2='''||New.CAMPO2||''',CAMPO3='''||New.CAMPO3||''' WHERE CAMPO1='||Old.CAMPO1||';');
end
END ^
SET TERM ; ^
Avevo scartato questa soluzione perchè in ogni caso va a forzare la scrittura di tutti i campi del record anche se ne è stato modificato uno solo. Ma alla luce dei fatti direi che è giusto così.