Newsgroup: it.comp.lang.visual-basic
Titolo: Cambio attributi in una relazione

 Su un DB Access vorrei cambiare 1 attributo ad una relazione gia esistente 
ma non me lo lascia fare.
Questo è il comando:
DB.Relations(1).Attributes = dbRelationUpdateCascade
Mi viene il sospetto che forse mi tocca cancellarla e reimpostarla tutta via 
codice. E' cosi?
-- 
Greg 

greg ha scritto:

Incredibile, non  mi lascia fare nulla su una relazione esistente. Come se 
ne esce?
-- 
Greg 

greg ha detto questo venerdì :

In genere, queste cose io le faccio con Alter...
Alberto
-- 
Georges Pompidou: Un uomo di stato è un politico che dona se stesso al 
servizio della nazione. Un politico è un uomo di stato che pone la 
nazione al suo servizio.

 In genere, queste cose io le faccio con Alter...
In un solo comando?
O prima cancelli, poi crei l'oggetto realtion gli crei e appienfii suoi 
cammpi e poi appendi anche lui?
Su, non farti pregare :)
-- 
Greg 

greg ha spiegato il 05/12/2008 :

Premesso che in genere lavoro su altri dbms, ma proprio concettualmente 
se devo fare delle modifiche al db, le faccio attraverso comandi Sql.
Per una foreign key (come immagino sia il caso che ti interessa), si 
usa l'Alter On Cascade, o cose del genere (non so cosa tu voglia fare, 
esattamente).
Alberto
-- 
Dentro la mia testa
ci son più bestie che nella foresta
[Jovanotti]

 (non so cosa tu voglia fare, esattamente).
Voglio poter cambiare il codice articolo, che è chiave primaria della 
tabella articoli.
Ma non si puo fare perche c'è un'atra tabella correlata che contiene quel 
codice.
Non ho mai fatto una cosa del genere; alter table e column ok, ma una 
relazione non mi era mai capitato.
S puo impostare con un solo comando sql che quando modifico il codice della 
prima tabella automaticamente si aggiorna anche nella tabella correlata?
-- 
Greg 

greg ha usato la sua tastiera per scrivere :

Non credo, perchè quando fai un update sulla chiave primaria della 
tabella Master, violi la constraint di foreign key, in quanto viene a 
mancare il collegamento.
Forse, ma dico forse, è possibile con un trigger Before Update, in cui 
prendi il codice precedente e te lo salvi in una variabile, poi 
inserisci un nuovo record con la nuova chiave, poi modifichi la foreign 
key nella tabella collegata facendolo puntare al nuovo record, e infine 
elimini il vecchio record. Ma se anche fosse possibile, sarebbe una 
mostruosità progettuale.
Le Primay Key non si modificano, per definizione...
Alberto
-- 
La bellezza è opinabile, sulla bruttezza sono tutti d'accordo.

 Le Primay Key non si modificano, per definizione...
Infatti non ne avevo mai avuto bisogno.
Ma ormai per troppa precipaitazine ho detto che si poteva fare.... no so è 
meglio inventarmi qualche pastrocchio o dire che non si puo :(
Stavo pensando:
- elimino relazione
- modfico tab1 e tab2
- rimetto la relazione
Ma a sto punto nulla è piu sicuro :(
Senza contare: se qualcosa si inceppa nel durante?
-- 
Greg 

 Senza contare: se qualcosa si inceppa nel durante?
Beh, per questo basta una transazione aperta, che oltretutto è 
d'obbligo per qualunque operazione non atomica.
Alberto
-- 
Thomas Fuller: Ci sono persone che sono state considerate coraggiose 
perchè avevano troppa paura per scappare.

 al cliente?
Eh..... ho usato una cosa che sembrava sicura: il codice articolo, o il 
codice fiscale.
Finche non ha record correlati pemetto anche di poterlo cambiare se uno ha 
fatto errori di isnerimento. Poi non è piu possibile.
Asesso mi dice che avrebbe piacere a poter coregger un paio di errori che 
hanno messo dentro, li per li gli ho detto ok, dammi 5 minuti, senza penzare 
che quel campo è una key usata anche in un'altr atabella.
-- 
Greg 

 che quel campo è una key usata anche in un'altr atabella.
Va beh, se è una cosa 'una tantum' da fare a mano, risolvi con qualche 
client amministrativo.
Ma se vuoi che il cliente possa fare questa cosa strutturalmente, devi 
cambiare strategia.
Alberto
-- 
Noi ammazziamo solo per motivi buoni.
E quando sono buoni, sta a noi indicarlo.
[Guccini]

 statement SQL).
[...]
Vabbe'... ho dovuto utilizzare DAO.CreateRelation anzichè lo statement SQL
in modo ad impostare gli attributi prima di associare la relazione alla
tabella.
Miscrosoft 1 termoPilucco 0
-------------------
http://groups.google.it/group/it.comp.lang.visual-basic/browse_thread/thread/35726bb60ef41ebc?hl=it&ie=UTF-8&q=creare+relazione+dao+group:it.comp.lang.visual-basic#cbf234e7633dca3e
-- 
Greg 


Risolto; aesso devo uscire poi scrivo come ho fatto
-- 
Greg 

 Risolto; aesso devo uscire poi scrivo come ho fatto
Allora me la sono cavata con 3 query invece di alterare la struttura del 
database.
- insert into tab1 values(new_cod)
- update tab2 set tab2_cod = new_cod where tab2_cod = old_cod
- delete * from tab1 where tab1_cod = old_cod
Il tutto tra begin e commit trans per avere tutto o niente.
In pratica metto un nuovo codice in tab1, collego a questo nuovo codice 
tutti i record connessi di tab2, infine cancello da tab1 il vecchio codice, 
che non avendopiu figli in tab2 posso cancellarerlo senza volare le regole 
di integrita del db.
-- 
Greg 

greg ha usato la sua tastiera per scrivere :

Quindi hai letto il mio post delle 16:36 ;-)
Io ti scrivevo di mettere questa cosa in un trigger, per consentire 
l'operazione di modifica in modo 'trasparente' all'utente.
Tu l'hai eseguito da finestra Sql, ma la storia è quella...
Ciao
Alberto
-- 
Heinrich Zille: Ognuno crede che l'altro sia come se stesso, 
dimenticando che al mondo esistono anche delle persone oneste.

 Alberto
Esatto, anche se hai chiuso  dicendo che è una mostruosità. Hai ragione, ma 
ormai l'errore era fatto e io non avevo altri modi per rimediare.
Per curiosita, hai letto il 3d dove termopilucco dice di aver cambiato gli 
attributi di una relazione esistente?
Peccato non abbia postato il codice :(
-- 
Greg 

zac totale
Oggi ho un po di tempo...posso fare alcune prove!
Tu mi parli di Access...e molti lo "sputano" come DB relazionale "poco
serio"...la mignottona dei db!!! eh eh eh
Cominciamo a dire
Master --->uno a molti--->Slave
A01 Intestazione fattura
A01 r1 Riga fattura
A01 r2 Riga fattura
A01 r3 Riga fattura
A01 r4 Riga fattura
A0176 Intestazione fattura
A0176 r1 Riga fattura
A0179 r2 Riga fattura
Se la intestazione A01 la fai diventare A02??? le povere righe
diventano orfane!!!
La via corretta sarebbe
Leggo i dati da modificare
Me li salvo temporaneamente
Cancello i dati
Introduco un nuovo movimento con il codice corretto
reintroduco i dati salvati temporaneamente
Chiudi tutto dentro una transaction
e vivi tranquillo....lo dico per Access...ma pensa sia la solita cosa
anche per altri DB "seri"...
almeno per SQLserver puoi fare una stored di comando che faccia questo
per UNA fattura....ma non vedo il motivo di farlo!!!
Il problema invece può essere:
ristrutturazione aziendale..analisi errata...disguidi tecnici....
insomma alla fine (come mi sembra nel tuo caso) Il codice NON l'ho
dato A FINI INTERNIper collegare fra loro records)....ma in una botta
di follia...
ho usato la numerazione delle fatture come codice e come primary
key....ossia mi sono sparato nelle palle!
La follia è che clienti diversi potrebbero usare numerazioni diverse:
numeri, lettere,combinazioni. Dovrei tener traccia dei progressivi,
controllare l'esatta progressione.
Riordinare numerazioni in caso di cancellazione(un conto farlo su un
campo e un conto farlo su una primary key correlata)...etc etc
Consiglierei di ristrutturare il db...caso mai come ver 1.2 da dare al
cliente più o meno gratuitamente!
Comunque in Access
se almeno la lungimiranza di:
impostare l'integrita referenziale
E ANCHE
Cancellazioni e Aggiornamenti a cascata
come ti cancella master e slave da dentro access...ti cancella anche
la relazione!
allora con (l'ho provato in VBA dentro access...quindi vai di DAO...)
un semplice
CurrentDb.Relations.Delete (<nomerelazione>)
es.
CurrentDb.Relations.Delete ("MasterSlave")
TE LA CAVI!
MA se invece non l'hai impostata in un impeto di controllo
referenziale???
Beh caro greg...ho fatto una prova:
Access2003
Tab Master correlata uno a molti a tab Slave
Impostata SOLO integrità referenziale
Riempio Master e slave
Seleziono u record master "cancel"
"Impossibile modificare o eliminare record. La tabella "slave"
contiene recor correlati"
Benissimo!
Ma un click sulla solita maschera e lo scatenamento di
CurrentDb.Relations.Delete ("MasterSlave")
ME LA TOGLIE!
Quindi posso modificare quello che voglio!
Il problema è semmai un altro...quando la "riattacchi la relazione" se
ci sono record "zoppi" ...orfani di padre...si rifiuta di
"riattaccarsi"....giustamente!
In altri termini
siamo in procedure ai limiti della decenza informatica....non
abusarne!!!
p.s.
IMHO...devi istanziare DAO....e riferirti SEMPRE come DAO.relations da
codice per avere la certezza di far eseguire queste "porcherie" da jet!

 zac totale
zac totale pure io altrimenti devo rispondere riga su riga.
Il db penso di averlo fatto bene, con l'integrita refernziale impostata, 
infatti è riuscito a difendersi pure dal suo padrone :) Certo ho sbagliato a 
scegliere la chiave primaria.
Ho impostato, a suo tempo, l'integrita referenziale ma non  "Cancellazioni e 
Aggiornamenti a cascata" pensavo non fosse una cosa buona. Se c'è da 
cnellare aggiornare qualcosa meglio che avvenga esplicitamente via codice e 
non come effetto secondario di un altro evento.
Immagina un noleggiatore con 6 auto in croce:
Auto Blu
Punto
Punto GPL
Auto Sposi
Ferrari
Lancia
Gli dico stai attento come scrivi, sono poche, se sbagli elimini e rimetti. 
Ok, ma adesso l'Auto Blu p stata verniciata rossa !!!
E quel nome li non si può piu toccare!
Da codice dao in vb (e db in acc97) io non dono riuscito a deletare per 2 
minuti una relazione, fare le mie porcherie sul db e rimmettere la 
relazione. Sembrerebbe che il metodo delete, che pure c'è, si possa usar 
quando una relazione è stata creata ma non ancora attacata e salvata con 
l'append. E qui mi chiedo che bisogno c'è di cancellare una relazione non 
ancora salvata?
Me lo attacco al monitor:
LA PRIMARY KEY NON SI MODIFICA, MAI.
Se serve modificare, allora vuol dire che non era quella la PK
-- 
Greg 

 Se serve modificare, allora vuol dire che non era quella la PK
Nel tuo esempio, il codice è parlante. Ed è uno dei pochi casi in cui è 
frequente vederlo cambiare. A maggior ragione in situazioni come 
questa, è fondamentale tenere distinte la primary key che si usa per le 
relazioni, da una colonna unique pseudo-descrittiva. Questa servirà per 
il catalogo, come codice 'umano', per tutto quello che vuoi, ma non 
sarà mai usata per nessuna relazione.
Io ho anche un'altra cosa che tendo a fare. In una tabella anagrafica 
qualunque, io ho diverse colonne:
Record_ID: spesso identity, a volte uniqueidentifier, comunque è chiave 
primaria e serve per le relazioni.
Stato: 0 per record valido, 1 per record eliminato o obsoleto
Codice: è la chiave 'umana' di individuazione del record. Nel tuo 
esempio, sarebbe "Auto Blu".
CheckCodice: è una colonna calcolata, che è uguale a Codice se lo stato 
è 0, ed è uguale a Record_id (più un preambolo) se lo stato è 1. Su 
QUESTA colonna impongo il vincolo Unique.
In questo modo, io posso avere in tabella questi record, senza alcun 
problema:
Id   Stato   Codice      CheckCodice
001    1     AutoBlu     PK001
002    0     AutoRossa   AutoRossa
Se adesso qualcuno cerca di codificare una nuova AutoRossa, l'insert 
fallisce perchè la colonna CheckCodice verrebbe a contenere AutoRossa e 
questo violerebbe il vincolo Unique.
Se invece prima di inserire una nuova AutoRossa, cancella il vecchio 
record autorossa, ottiene la configurazione
Id   Stato   Codice      CheckCodice
001    1     AutoBlu     PK001
002    1     AutoRossa   PK002
003    0     AutoRossa   AutoRossa
Se adesso AutoRossa deve diventare AutoVerde, si arriva a:
Id   Stato   Codice      CheckCodice
001    1     AutoBlu     PK001
002    1     AutoRossa   PK002
003    0     AutoVerde   AutoVerde
senza aver rotto alcuna relazione.
E nulla vieta di recuperare, anche lato client con una opportuna select 
che non escluda Stato<>0, i record eliminati. Anche se ovviamente non 
sarà possibile recuperare un record se il Codice va in conflitto con 
uno attivo.
ciao
Alberto
-- 
Charles Baudelaire: C'è un solo modo di dimenticare il tempo: 
impiegarlo.

 003    0     AutoVerde   AutoVerde
Questa è la via che seguo, tranne alcune volte che ho usato scorciatoie per 
cose che ritenevo molto semplici.
L'ID numerico per le relazioni e il Codice per gli umani. E gia questo mi 
mette in una botte di ferro. E basta; 2 sole colonne.
Con le colonne Stato e  ChekCodice vedo invce che tu ti aspetti, e sei 
prepatato, tutto e il contrario di tutto. Mi riservo di approfondire meglio 
queste 2 colonne.
Grazie davvero della disponibilita e ... della lezione :)
-- 
Greg 

 Wodka40[Google] ha scritto:
Ognuno alla fine fa come vuole....
io ho provato su un file con tabelle cariche e cambiando e ricmabiando
un po di record......
non ho per fortuna da mooolto tempo per le mani access/office 97
IO so solo che mi è capitato anche a me
Autofficina....gestione revisioni
La cosa la risolvi in due modi
Chiamo con un mio codice la macchina e comunque mi faccio sempre
mettere un contatore...è comodo avere un rif. tramite un id che è un
SOLO valore!
Mi prendo qualche rischio relativo...
per le auto....la targa (specialmente ora che ci si porta dietro...o
il numero di telaio ancora meglio)
per le persone CF o PIVA
Solo che avere un codice interno...."è troooooppo meglio"...ogni tanto
il meteorite cade: ti capita 2 macchine con la solita targa/numero
telaio....una ditta con 2 sedi nella solita città!
IMHO lo sbaglio è stato dare la possibilità di codici parlanti
Magazzino
IDinterno....primary key
CodCliente .....testo
Descrizioni e campi vari
A che serve questa inutile complicazione ?
PIPPO usa come codice dei prodotti un alfanumerico di sua costruzione
PLUTO un ISBN
PAPERINO solo numeri
DE PAPERONI...hai visto bellino al tg di venerdì? Una immagine che se
inquadrata da una cam viene decodificata in un codice! (l'avevano
sulle forme di formaggio ad uno stand italiano in Cina...il cinesino
inquadrava l'immagine con il telefonino e veniva collegato alla pagina
web che in mandarino gli spiegava che cavolo di formaggio comprava)
Che fai?....modifichi 4 volte il database???
La macchina verde diventa blu?
Le rondelle "High"...diventano "strong"?
La camera "Orietta" ...diventa "Paradiso Tropicale" perchè il
marketing ha avuto una idea?
Che fai?
Roba come quella appena fatta?
Io sono sempre dell'idea: fatemi lavorare tanto e tutto insieme...però
poi...e fatemi campà tranquillo!
Della serie: un programma risolve problemi al cliente...ma anche al
programmatore...se invece li crea...c'è qualcosa di sbagliato!
....e sapessi quanti ne ho sbagliati ( e ancora persisto eh!!!)

 ....e sapessi quanti ne ho sbagliati ( e ancora persisto eh!!!)
Wodka... guarda che siamo perfettamente daccordo.
Questa era una vecchia cosa fatta, male, ma vecchia. E sicuro a quel tempo 
non mi eroc ancora covnertito al fatto che la PK è sacra e una, non trina :)
-- 
Greg 

 Wodka... guarda che siamo perfettamente daccordo.
Ma poi la curiosita ea su come Termpopilucco fosse riuscito a togliere una 
Relation, fare le sue modifiche  e rimettere la Relation al suo posto. Da 
codice dentro una sub di vb, certo, e non dall''intefaccia di Access
-- 
Greg 


SIGH! e pure sob!
<sospirone>
se l'ho fatto da DENTRO VBA......con il 2003
il 2003 lo fa anche da codice che non sia vba....
e che cosa non sarà VBA????
MAH!
e Access esporrà una interfaccia COM? ...boh!
e VB6 VB.net potrà usare DAO???
Bof!
Una relation non la puoi fare SE non riesci a correlare TUTTI i record
della tabella correlata...ne lasci uno?....NON puoi "ri correlare"
SE non te la fa rifare....qualcosa rimane orfano!
Dai greg non mi fàr fare un "progettillo" vb6!!!
Se nei riferimenti del progetto metto DAO
VB 4 5 6 C# VB.net Java C++ Haskell Lisp Python...etc
avrò sicuramente un DAO.<qualcosa>
casomai il punto sarà sostituito da qualcos'altro....ma un namespace
DAO mi dovrebbe apparire!!!
p.s.
Per fare modifiche così "sostanziali"....sarebbe importante aprire
anche l'mdb in "accesso esclusivo"!....se qualcuno ti usa le tabelle
diventa difficile modificarle!!!
Va bene che Access  non viene considerato come un database....ma
parecchie obiezioni sono solo "paturnie"!!!

Bof!
quindi EOH = end of hope? :)

 diventa difficile modificarle!!!
Si, il dao espone la collection Relations che ha il metodo delete
E accetta MioDB.relations.delete nome
Ma a me da errore (impossible bloccare tabella) anche aprendo il db in 
esclusviva
Il discorso del ricollegarla verrebeb dopo, eventualmente.
Ho usato dato dao 3.6 e questo codice:
Dim NomeRel
For n = 1 To .Relations.Count
    If .Relations(n).Table = "Tab1" and  .Relations(n).ForeignTable = "Tab2" 
Then
            NomeRel = .Relations(n).Name
            Exit For
    End If
Next
DB.Relations.Delete (NomeRel)
-- 
Greg 

 Wodka40[Google] ha scritto:
probabilmente c'è qualcosa ce non và....io adesso non poso
provare....domani se ho tempo riapro vb6 e cerco di buttare un po di
codice.....
Cmq
fatti un nuovo progetto che usi il tuo mdb
e prova stò codice
http://support.microsoft.com/kb/129879/it
Si però caro mio....ti sei accorto che DAO 3.6 va da 2000 in poi???
se usi un off97
o converti  l'mdb in 2000 almeno
o usi DAO 2.5 - 3.5.1 al massimo!!!
e ci possono stare tutte nel progetto come riferimenti...e per usare
una per una altra devi dichiarare tutto il namespace!
es DAO360.Relations DAO351.relations
http://ennius.interfree.it/vba/dbbase1.htm

 
http://support.microsoft.com/kb/129879/it
Si, effettivamente qualcosa teneva il db aperto.
Provato su progetto nuovo e cancella effettivamente tutte le realzioni
A rimetterle a posto invece.... è molto piu complciato.
Non si puo copiare momentaneamete la relation che si vuole cancellare dentro 
un oggetto relation per poi alla fine ricopiarla con tutti i suoi attributi 
dentro il database.
Boh domani provo meglio
-- 
Greg