Newsgroup: it.comp.lang.delphi
Titolo: Cancellare a cascata tra master e detail

Due domandine sui database...
-- per cancellare i dati detail quando cancello un master, senza rivolgersi a query o simili, vorrei usare direttamente la gestione dell'integrità
riferenziale di paradox. Perciò da Database Desktop ho settato per la tabella detail sotto "Referential Integrity" il legame con la tabella master, e
poi selezionato "Cascade" come regola di Update. Finché modifico la primary key nella tabella master, tutto bene, il cambiamento si riflette nella
foreign key della tabella detail, ma se provo a cancellare il dato dalla master, ottengo un'eccezione che mi dice che non posso cancellarlo perché ci
sono dati altrove che si riferiscono ad esso, e quindi si comporta come se fosse impostato "Prohibit" come regola di Update anziché "Cascade". Come
fare? Gli help di Database Desktop fanno l'esempio esplicito di cancellazione di un record master che si propaga al detail, quindi non capisco cosa
sto tralasciando.
-- una più... "filosofica": nel classico scenario dell'archivio di gestione clienti, cosa usare come chiave primaria? Leggevo sul gruppo tempo fa che
gli AutoInc hanno seri problemi. Ovunque si consiglia di usare il codice cliente, ma come ottenere il codice cliente? Per ora ho risolto usando in una
stringa il datetime (sottoforma di float) del momento di inserimento del record, ci sono soluzioni un po' più eleganti, che magari stanno anche in un
integer?
Massimiliano

integer?
puoi usare delle tabelle contatore.
se poi passerai a un sql server potrai sostituirle agevolmente
con sequence o generator...

 puoi usare delle tabelle contatore.
Cos'č una tabella contatore?
Massimiliano

Non ho mai usato l'integrità referenziale in Paradox, ma non ti consiglio di
farlo! Non è bene cancellare record da un archivio in modo automatico,
l'utente potrebbe ottenere risultati che non si aspetta, e comunque è meglio
che sia lui a prendersi la responsabilità di eliminare dei dati in modo
permanente.
Ti vorrei poi far notare una cosa che ti dovrebbe fare pensare, e cioè che
mentre paradox e il jet hanno un metodo di eliminazione in cascata SQL
server e Oracle non ce l'hanno! (forse i programmatori Oracle non hanno
voglia di lavorare..?)
Per gli Autoinc il problema di solito si ha con la gestione multiutente dei
database, se contemporaneamnete si utilizzano sistemi tipo aggiornamenti in
cache o simili (vedi anche Midas). In questi casi si può avere il problema
di sincronizzare la query e i dati reali del DB nel momento in cui si
conferma l'inserimento di un record. Si verifica che mentre nel DB viene
assegnato il valore del contatore la cache sul PC Client non ha modo di
conoscere il valore assegnato dal DB, e si può avere una situazione simile a
quella cha si avrebbe quando un secondo utente modifica un record. (In
effetti D4 dà un errore del tipo "record changed by another user") In D5 se
si usa il componente TClientDataSet si può ovviare al problema.
L'alternativa può essere quella di realizzare una tebella di progressivi da
consultare e aggiornare manualmente ad ogni richiesta di un nuovo
progressivo. Anche così però le cose si possono complicare se si lavora in
multiutenza e non si può ammettere la perdita di progressivi (esempio numero
fatture).

Cos'č una tabella contatore?
molto semplice: contiene una riga con una colonna
che mantiene l'ultimo numero utilizzato (il contatore
appunto), quando ti serve un nuovo valore blocchi la tabella
leggi-usi-e incrementi il contatore.
non e' molto elegante ma si puo' convertire molto in fretta
se un giorno passi a qualche sql server.
alcuni usano un altro metodo (che a me non piace),
al posto del contatore generano un numero casuale
a 64 bit.