Newsgroup: it.comp.lang.visual-basic
Titolo: Cancellazione record con LEFT JOIN

Salve a tutti, ho un problema che non riesco a risolvere:
ho due tabelle .mdb
tabella1   con campi    campo1,campo2,campo3
tabella2   con campi    campo4,campo5  (quest'ultimo lo uso come
chiave di collegamento)
creo un recordset con SELECT campo1,campo2,campo3,campo4 FROM tabella1
                 LEFT JOIN tabella2 ON tabella2.campo5 =
tabella1.campo3
Funziona bene. Quando però vado a cancellare un record da tabella1 col
comando tabella1.Delete, mi cancella anche la riga in tabella2 che
contiene la chiave interessata, anche se in tabella1 ho ancora altri
record che corrispondono a quella chiave.
Non so se sono riuscito a spiegarmi, io comunque vorrei che in
tabella2 non venisse mai cancellato nulla, voglio solo cancellare un
record da tabella1.
Un'anima buona mi darebbe un consiglio su come fare?
Grazie dell'attenzione   :)

 Un'anima buona mi darebbe un consiglio su come fare?
io non ci ho capito molto, ma a naso direi che ti basta rimuovere le 
cascade delete dalla relazione tra le tabelle.
.m
-- 
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com
blog @ 
http://milestone.topics.it
whynot [ at ] topics [ dot ] it

 cascade delete dalla relazione tra le tabelle.
Ciao Mauro, grazie intanto della risposta, ma in realtà non ho usato
nessun cascade delete, la relazione tra le tabelle è impostata proprio
dalla creazione stessa del recordset con la sintassi che ho scritto
nel primo post (uso VB6).
Se cancello un record da questo recordset, mi cancella la relativa
riga di entrambe le tabelle "sottostanti", ed è questo il
comportamento che vorrei evitare, io vorrei cancellare solo da una
tabella ...
mi sta iniziando a sorgere il dubbio che è un comportamento normale
per come ho creato il recordset?
ma allora quando si usa un JOIN non si può cancellare un record?
Mi servirebbe un lume da voi esperti...
Grazie

Amilcare ha scritto:
Mi viene in mente una proprieta (cancella record correlati a cascata o 
qualcosa del genere) nella prima tabella.
Puo darsi che sia impostata a true.
-- 
Greg 

Se hai definito delle relazioni fra le tabelle e hai specificato di 
mantenere l'integrità referenziale, per forza di cose, se sparisce un 
record da una tabella sparisce anche in tutte quello che lo referenziano.

 ma allora quando si usa un JOIN non si può cancellare un record?
Usa un comando SQL e sei sicuro di fare un lavoro fatto meglio.
Alberto

Puo darsi che sia impostata a true.
Oddio, qual'è 'sta proprietà?
Grazie a tutti

 Oddio, qual'è 'sta proprietà?
Non conosco Access a questo punto.
Alberto

mi sa che dovresti studiare un po ...un minimo...di teoria dei db
relazionali...il sito 
html.it
 c'ha una sezione database!
in parole povere terra terra
se usi un database relazionale...lo dice il nome...puoi stabilire
relazioni fra tabelle!
Le relazioni possono essere di vari tipi...1 a 1 1 a molti molti a
molti
L'esempio che faccio sempre nei corsi
1 a 1
è un modo comodo di spaccare una tabella in due. Perchè farlo? Per
chiarezza concettuale...oppure perchè il db usato non ti fà usare
tabelle con più di 255 campi!
ad esempio
la tabella alimento è relazionata 1 a 1 con la tabella vitamine per
comodità
Consulti la tabella alimento "Peperone" e appare nella tabella
vitamine UN SOLO record che riporta la quantità di vitamine del
peperone
1 a molti
Autore -> Libri
Un autore scrive molti libri
Nella tabella autori scegli un nome "Manzoni" e ti lega i
corrispondenti record nella tabella libri che sono legati al Manzoni
molti a molti
Sempre nei libri
E se un libro è scritto da più autori? E se questi scrivono anche
altri libri in proprio?
Abbiamo bisogno di una relazione "molti autori" che scrivono "molti
libri"
Direttamente questa relazione non la gestisce nessun database
"normale" a parte credo postgresql su alcuni tipi dati....si gestisce
con le "tabelle cross" (a te approfondire ma sono facili)
DETTO QUESTO
l'appetito vien mangiando.....
nella pratica forse lo saprai l'utilizzatore è un imbranato
totale...fa dei casini immani tanto da meritarsi l'appellativo di
utonto
Caso tipico,,,,,cancello il "Manzoni" nella tabella
autori....PANICO....ho decine di libri rimasti "zoppi": a chi cazzo si
riferiscono?
Peggio ancora...pensa se fossero ordini da evadere e gli cancelli il
cliente a cui spedire la merce...un danno incredibile!
Allora si inventa l'integrità referenziale:
tu non puoi cancellare un record PADRE se prima non gli ammazzi i
FIGLI!!!
Quindi non puoi cancellare il manzoni se prima non togli dall'archivio
i libri che si riferiscono a lui!
Non puoi cancellare il cliente se prima non togli gli ordini che si
riferiscono a lui!
Bingo!
MA...l'appetito vien mangiando...e l'ammazzacaffè ci stà bene!
Se hai dato un codice al Manzoni...può darsi che tu cambi metodo di
codifica( ad esempio perchè la tua libreria viene assorbita da un
grande catena)
e quindi i codici dei record da  ABqualcosa diventano AXX-
AB00000qualcosa!
Panico Paura! mi devi ricodificare tutto?
NO
perchè nell'integrità referenziale hai impostato "aggiorna campi
correlati a catena" (in access si chiama così ed è una casella di
spunta che ti appare visualizzando le proprietà della relazione)
E' COSA BUONA E GIUSTA farlo....normalmente non ti porta casinio...ed
anzi ti aiuta nella corretta gestione del tutto
Veniamo al conto...hai mangiato...mo devi pagare!
Ci sono casi in cui vorrei pulire l'archivio!
Ad esempio....non lavoro più con un cliente e mi ha saldato tutto!
Inoltre sono anche in un altro anno fiscale....
VOGLIO CANCELLARE IL CLIENTE e tutto quello che si riferisce a
lui...ordini...pagamenti...tutto!
Devo spuntare "cancella record correlati a catena"
MA è una cosa pericolosisssssssssssssssssssssima!!!
Va fatta SOLO se si sà cosa si sta facendo!
Se per un bug di codice cancelli un cliente....cancelli anche i
movimenti correlati!!!!
Se il tuo db cancellando un cliente cancella i corrispondenti...vuol
dire che ha spuntato "cancella record correlati a catena"
ripeto...un po di teoria.....ad esempio
tu parli di left join...che è una cosa diversa ancora...
il legame lo fai solo durante la query e non è presistente
Autore -left join -> Libri
in pratica dice
Dammi tutti gli autori e anche i libri che hanno impostato l'autore!
Se hai lasciato in bianco l'autore questa query lo salta!
Se invece hai impostato l'integrità referenziale
NON POTRAI MAI creare un record "libro" che HA vuoto il campo autore
viene da se il maggior grado di robustezza nei confronti
dell'utonto ...lo capisci vero?
Saluti!

 Saluti!
Allora, anzitutto grazie a tutti delle risposte, lo apprezzo molto.
Nel mio caso in particolare, io ho degli utenti-clienti (tabella1, la
"principale"), ognuno dei quali è assistito da un avvocato; siccome
gli avvocati sono un po' sempre gli stessi (una trentina), io invece
di riscrivere ogni volta che ho un nuovo cliente tutti i dati
dell'avvocato nella tabella dei clienti, ho creato una tabella
"Avvocati" (tabella2, la "secondaria"); tale tabella contiene tutti i
dati relativi ad un singolo avvocato, ed anche un campo
"DenominazioneAvvocato" che mi crea un legame con il cliente.
Creo un recordset con
SELECT cognomeCliente, nomeCliente, FaxAvvocato FROM tabella1 LEFT
JOIN tabella2 ON tabella2.DenominazioneAvvocato = tabella1.Avvocato
I campi cognomeCliente, nomeCliente sono tratti dalla prima tabella
(quella dei clienti), mentre il campo FaxAvvocato è tratto dalla
seconda. Per funzionare, funziona.
Solo che quando vado a cancellare un cliente tramite Recordset.Delete,
mi cancella anche il corrispondente avvocato dalla tabella Avvocati,
cosa ovviamente indesiderata!
Ripeto, mi sorge il dubbio che sia un comportamento normale...?
Voi che ne dite? Grazie ancora

 "DenominazioneAvvocato" che mi crea un legame con il cliente.
Immagina di fare tutto su carta.
Compri i registri da buffetti, uno per gli avvocati, uno per i clienti.
Quello degli avvocati fila liscio: numero, nome, cognome, tennis, amante 
ecc....
Il registro dei clienti: ci metti il numero, nome, cognome e poi ... nel 
campo avvocato cosa ci metti?
Ne prende 1? due? Tre?
Ecco, questa è la prima grossa decisione da prendere: fai 3 capi (3 colonne) 
avvocato? O fai 2-3 righe e ripeti i dati del cliente tante volte quante 
sono gli avvocati?
Oppure metti il codice del cliente nle registro degli avvocati?
Oppure fai una terza Tabella (cause) e ci metti solo il numero avvocato, 
numero clienti, e il campo aperta/conclusa.....
Cosa è meglio per il tuo lavoro?
-- 
Greg 


Dico che c'hai una relazione uno a molti impostata con delete a
cascata...
usi access?
vai in "relazioni" e guarda quello che viene fuori!

 Cosa è meglio per il tuo lavoro?
Beh anzitutto ogni cliente è sempre assistito da uno e un solo
avvocato, non ci sono clienti che non ne hanno, non ci sono clienti
che ne hanno più di uno. Detto questo, io nella tabella avvocati ho
previsto un campo "denominazioneAvv", univoco per ciascun avvocato;
quando inserisco un nuovo cliente, non faccio altro che scegliere da
una combobox una di queste denominazioni (prese appunto dalla tabella
avvocati) ed ecco che il cliente è associato all'avvocato che lo
assiste.
Ripeto, funziona bene, solo che quando cancello il cliente (da
recordset, v. post precedenti) mi cancella anche l'avvocato dalla
tabella avvocati ...

 wrote:
posto che tutto è possibile....e quindi potrei essermi bevuto il
cervello...alla fine mi hai fatto aprire access e
Creato 2 tabelle
Cliente con
IDcliente contatore
e un po di campi
e un campo IDlegale intero lungo
POI
una tabella legali con
IDlegaleattivo contatore (cambiato nome per non farti confusione)
e vari campi
Andato in creazione query e creato una banalissima
SELECT Clienti.Denominazione, Legali.Denominazione
FROM Clienti LEFT JOIN Legali ON Clienti.IDlegale =
Legali.IDlegaleattivo;
Mi riporta i clienti e se ce l'hanno il legale assegnato
presa una riga di un cliente che abbia un legale assegnato ( e che è
assegnato anche ad altri clienti) e CANCELLATA
TA DAH....l'avvocato non viene eliminato...il cliente si...come è
anche purtroppo nella realtà dei fatti!
Quindi era logico anche prima ....ma sono sicuro al 100%
come detto
SE NON HAI impostato l'integrità referenziale con il cancellamento a
cascata
E' un tuo bug logico: da qualche parte lo cancelli casomai perchè hai
una relazione che cancella a catena o qualche flag che è settato per
canccelare i record correlati in una griglia o che ne so!...cmq non è
colpa di access ne tantomeno di sql

 tabella avvocati ...
Premetto che non ho MAI fatto un'operazione del genere da recordset, ma 
solo da comando Sql.
Però, se tu hai un recordset che rappresenta una vista di join fra due 
tabelle, cancellando un record del recordset tu cancelli i 
corrispondenti record su entrambe le tabelle, e questo ha anche una sua 
logica (se fai un delete di una cosa composta di due parti, quale delle 
due parti stai chiedendo di eliminare?).
Ripeto il mio consiglio precedente: fai tutto con comandi sql (e, 
magari, rivedi anche quella struttura 'monoavvocato', che mi sembra 
molto limitata).
Alberto

 Scriveva Amilcare sabato, 29/01/2011:
mi sembra che in uno dei tanti post abbia detto che usa access?
....credo che le viste in access non abbiano equivalente (se non
facendo un create table come workaround).
Non ho sottomano un vb6 però mi sembra che ADO cancellasse solo il
record non a catena.
Non la considera una vista...se fosse una vista invece si...avresti
ragione
Dalla Gui Access la considera una query e cancella solo quel record
lasciando integri gli altri
Ora rimane da chiedersi....non è che lui lavora su una vista? E non su
Access?