Newsgroup: it.comp.lang.delphi
Titolo: [caCascadeDeletes] in TDatasetProvider.Options con Firebird

Salve,
sto utilizzando dbExpress (Deplhi6) con TDatasetProvider e
TClientDataset per una gestione in Firebird dei movimenti di
magazzino (due tabelle in master/details: testata [cdMVH]
e dettaglio [cdMVR]).
Nonostante abbia strutturato l'integrità referenziale e
corrispondente CASCADE DELETES sul database,
dall'applicazione client in delphi non riesco ad ottenere
la cancellazione automatica dei records di details quando
cancello il corrispondente record master.
Ho impostato tra le options del TDatasetProvider il flag
[caCascadeDeletes] sperando di risolvere il problema ma
non appena tento di eseguire un ApplyUpdates del record
nel ClientDataset master si verifica una violazione di chiave
esterna sul ClientDataset details.
Non vorrei adottare delle soluzioni manuali del tipo:
cancellare manualmente i record di details nell'evento
OnBeforeUpdateRecord del TDatasetProvider.
Cosa fare ? Dove sto sbagliando ?
Qualcuno ha già utilizzato tale approccio con Firebird ?
Grazie,
Riccardo
-- 

 cancello il corrispondente record master.
Perchè non la implementi direttamente sul database, con un trigger sulla
After (o Before) Delete della tabella master?
	CREATE TRIGGER TFATTURE_AD0 FOR TFATTURE
	ACTIVE AFTER DELETE POSITION 0
	AS
	begin
	  delete from DFATTURE 
	  where ANNO   = old.anno 
	    and NUMERO = old.numero;
	end
In questo modo puoi garantirti sempre che se viene eliminato un record
dalla tabella master (in questo caso TFATTURE) anche la corrispondente
detail (DFATTURE) viene aggiornata.
Saluti
	Marco Bortolani
	info @ 
marcobortolani.it

 detail (DFATTURE) viene aggiornata.
Infatti è proprio questo che vorrei ottenere ma evitando di dover scrivere
del codice delphi oppure dei trigger ogni volta che mi si presenta tale
situazione... altrimenti a cosa servirebbe il CASCADE DELETES
impostato in Firebird sulla chiave esterna della tabella di detail ?
Ciao,
Riccardo
-- 

Come hai realizzato il M/D fra i client dataset? Utilizzando un solo
provider e i nested dataset o hai due provider separati e la relazione M/D
impostata in maniera "classica" fra i cds?
Luigi D. Sandon - D&amp;D Support Team
--- posted by geoForum on 
http://www.delphiedintorni.it

 OnBeforeUpdateRecord del TDatasetProvider.
Controlla bene la configurazione dei componenti perché il tutto funziona.
ciao
  gabriele

 impostata in maniera "classica" fra i cds?
Con un solo provider e i nested dataset.

 ha scritto nel messaggio 
news:cohdg0$pfg$1...@newsread.albacom.net...

Ok grazie, lo farň... ma tu hai esperienza di ciň proprio su Firebird ?
Utilizzando un solo provider ed i nested dataset ?
Ciao
-- 
Riccardo 

 Ciao
Ciao
  Gabriele

>Con un solo provider e i nested dataset.
Allora dovrebbe funzionare senza problemi. L'ho utilizzato tranquillamente
con Interbase, dovrebbe funzione anche con Firebird. A meno che non ci sia
qualche problema con il driver dbExpress, o in qualche impostazione del
provider o del database.
Anche perché il provider dovrebbe semplicemente ignorare i record "detail"
cancellati e generare una semplice "DELETE FROM master WHERE...",
aspettandosi che al resto ci pensi il database.
Prova a:
1) Fare una delete direttamente via SQL (senza passare per Delphi) e vedi
se il database funziona correttamente o no.
2) Prova a fare un trace degli statement SQL che riceve il DB per capire
cosa combina il provider.


Se hai una FK devi cancellare i detail prima del master, non dopo perché
scatterebbe un errore (almeno sui DB che implementano correttamente il
modello relazionale).
Ma i constraint ON .... CASCADE sono molto più comodi perché ti
risparmiano di scrivere il trigger tutte le volte, e sono associati
direttamente alla FK a livello di metadati e semplificano sia la scrittura
che la documentazione e la manutenzione.
Poi ci sono DB che implementano "male" le FK, imponendo troppi limiti,
come certe versioni di SQL Server o Oracle con le sue dannate tabelle
"mutanti".


Questo è l'errore che si verifica quando provo
a cancellare un record dalla tabella master.
violation of FOREIGN KEY constraint "FK_BAN_MVR_NUMVBH" on table "BAN_MVR"
dove
BAN_MVH è la tabella master
BAN_MVR è la tabella detail
FK_FK_BAN_MVR_NUMVBH è la chiave esterna della BAN_MVR relativa 
all'integrità referenziale tra BAN_MVH e BAN_MVR

 ha scritto nel messaggio 
news:41ac9898$1...@x-privat.org...

Sto utilizzando i seguenti componenti:
- qbMVH    TSQLDataset master
- qbMVR    TSQLDataset detail (collegato attraverso un DataSource a qbMVH)
- dpDSP    TDataSetProvider (collegato al Dataset qbMVH, con 
UpdateMode=upWhereKeyOnly)
- cdMVH    TClientDataset (con ProviderName=dpDSP)
- cdMVR    TClientDataset (con DataSetFiled=cdMVHqbMVR ovvero il 
TDatasetField corrispondente al nested detail di cdMVH)
Le options del Provider dpDSP sono: 
[poIncFiledProps,caCascadeDeletes,caCascadeUpdates,poAllowMultiRecordUpdate,poAutoRefresh].
Ho provato a modificare un po' le options del Provider ma non è cambiato 
nulla.
Intanto che continuo con le mie prove e tentativi vari spero di ricevere 
degli input risolutivi.
Grazie comunque a tutti,
Riccardo
-- 

Ok, tutto risolto.
Era un problema legato alla chiave esterna di Firebird... è bastato 
eliminarla e ricrearla e tutto ha funzionato.
Grazie a tutti per gli spunti, alcuni dei quali mi hanno permesso di venirne 
a capo.
Riccardo