Newsgroup: it.comp.lang.delphi
Titolo: Verifica se il record è duplicato

Ciao a tutti,
avrei bisogno di un'altro piccolo aiuto.
Sto sperimentando con Delphi 2010 e Firebird e vorrei qualche dritta su come 
fare per verificare, prima di inserire un record, se questo è già presente.
Ad esempio:
leggo in automatico da un file di testo alcuni record con campi separati da 
punto e virgola, i campi sono: data, data valuta , descrizione ed importo.
ad ogni lettura completa del record questo viene inserito tramite un 
Tsqlquery nel database Firebird.
Tutto funziona ma vorrei non inserire il record se questo esiste già nel 
data base.
Non avendo nessun campo nel file di testo sorgente che possa rendere univoco 
il record, ho pensato di fare un confronto sul contenuto di tutti i campi e 
se tutti coincidono viene rifiutato l'inserimento.
Esiste qualche sistema più elegante ?
 
Grazie a tutti. 
 
 

 Esiste qualche sistema più elegante ?
Questo meccanismo l'ho implementato nel mio software di acquisizione 
dati da un sistema di terze parti in modo identico al tuo: loro mi 
mandano periodicamente dei CSV e io li parso, estraggo i dati e poi 
faccio una insert nelle tabelle relative.
 
Ho messo nel db le pk opportune scartando così automaticamente per 
integrità referenziale i record duplicati.
Poi da sofwtare gestisco l'eccezione di fallito inserimento per loggare 
i warning (per me non è bloccante il fatto che ci sia un record 
duplicato che viene scartato, quindi il software di acquisizione gira 
indisturbato per giorni e giorni prima di chiuderlo per interventi).
 
quindi metti una primary key dove occorre e dormi tranquillo.
 
ciao
 
 
-- 
morde
QT 4.7
Delphi (5,6,7.. expired)
Firebird Database
 

 per giorni e giorni prima di chiuderlo per interventi).
 
Grazie mille,
ero già arrivato ad una soluzione simile
ma non riesco a gestire l'eccezione.
ho provato a fare questo:
 
 try
 
     sqlquery1.SQL.Text:= 'stringa comando sql')';
    sqlquery1.ExecSQL;
    sqlquery1.SQL.Text:='commit';
    sqlquery1.ExecSQL;
 
    except
    raise ERangeError.CreateFmt('Il record è già presente',[]);
 
(visualizzo una finestra in caso di record duplicato perchè sto facendo 
delle prove)
 
il programma quando trova un record duplicato genera un'eccezione, ma quando 
chiudo la dialogbox invece di tornare mi rimane il cursore a forma di 
clessidra come se l'applicazione rimasse appesa
Come si gestisce correttamente l'eccezione ?
 
Ciao e grazie nuovamente.
 
 

 Come si gestisce correttamente l'eccezione ?
 
premetto che sto programmando con QT e c++, tuttavia mi viene il 
sospetto che la clessidra magari indica che lui sta andando avanti a 
importare e non fa solamente il refresh della gui.
 
prova a commentare il dlg di notifica e limitati a scrivere su un 
textbox l'errore, vedi se cosě facendo funziona.
 
fammi sapere,


 fammi sapere,
 
Trovato l'errore.
Un classico errore da principiante:
all'inizio della procedura ho messo un screen.Cursor:=crHourGlass;
ed alla fine un screen.Cursor:=crDefault;
L'eccezione impediva il ritorno del cursore alla modalità di default...
Mi vergogno profondamente....
 
Comunque grazie per gli ottimi consigli
Ciao. 
 
 

     raise ERangeError.CreateFmt('Il record è già presente',[]);
 
 
xche prp erangeerror?
 
A.

 Mi vergogno profondamente....
 
Mal comune mezzo gaudio, ossia: benvenuto nel club di quelli che si 
fanno i muscoli a furia di alzare sacchi di cemento sulle spalle ;-)


 clessidra come se l'applicazione rimasse appesa
 
Se il tuo obiettivo è gestire il caso specifico, non puoi usare *except* senza aggiungere altro, perché in quel modo intercetti tutte le possibili eccezioni e quindi rischi di includere un errore diverso dal record duplicato nella casistica: verifica qual è l'eccezione che si verifica quando il record è duplicato e utilizza quello.
 
Non usare *ERangeError* perché ha un significato preciso nella libreria VCL e quindi il suo impiego per segnalare un record duplicato rilanciando una eccezione diversa dall'originale è senz'altro improprio.
 
Sul cursore a clessidra, non ricordo che la libreria "dbExpress" lo utilizzi automaticamente come suggerimento visivo: sei tu a impostare quel cursore quando effettui l'operazione sui dati? In caso affermativo, devi inserire le istruzioni all'interno di un blocco *try...finally* per garantire che venga ripristinato il cursore originale, qualsiasi cosa accada durante l'elaborazione dei dati.
 
Un esempio di codice giusto per illustrare il concetto:
 
 Screen.Cursor := crHourglass;
 try
   // ...qui l'elaborazione dei dati...
 finally
    Screen.Cursor := crDefault;
 end;
 
Ciao,
  Marco.
 
-- 
MARCO BREVEGLIERI
#Home: 
http://www.marco.breveglieri.name
 
#Blog: 
http://www.compilaquindiva.net
 

 raise ERangeError.CreateFmt('Il record è già presente',[]);
 
 
xche prp erangeerror?
 
Non 'c'è una ragione precisa,
rincipalmente sto facendo alcune prove con firebird e visto che non riuscivo 
a gestire l'eccezione (per altri motivi) ho fatto una serie di tentativi...