ON DELETE CASCADE ... SOS!!!

domenica 04 marzo 2007 - 12.47

dilaora Profilo | Newbie

Salve a tutti,
avrei la necessità di creare da script l'intero Database della mia modesta applicazione, con Tabelle, relazioni, chiavi primare, indici etc. .

Riesco abbastanza facilmente a creare una struttura di base ma incompleta, infatti creo tabelle, chiavi e relazioni, ma non riesco ad impostare le clausole "ON UPDATE CASCADE ON INSERT CASCADE", quello che praticamente si fa nella maschera delle relazioni in ACCESS andando sulle proprietà della relazioni e impostando il baffo a "Aggiorna campi correlati a catena" ed "Elimina record collegati a catena".

Vi posto uno scorcio di codice che utilizzo:

--
-- START SCRIPT SQL
--
CREATE TABLE Utenti
( username varchar (50), idRuolo Long, passw varchar (50) );

ALTER TABLE Utenti ADD CONSTRAINT FK_Utenti_Ruoli FOREIGN KEY (idRuolo) REFERENCES Ruoli (id ) [ON UPDATE CASCADE ON DELETE CASCADE];
--
-- END SCRIPT SQL
--

L'Alter in ACCESS viene eseguita senza dare messaggi di errore o warning, ma se vado a vedere la relazione i due baffi non ci sono!!

Vi è capitato anche a voi?
Non è che via codice non si puo fare (credo che si possa fare!)?
Sapreste indicarmi la soluzione?

N.B.: per la cronaca Utilizzo MS ACCESS 2002

Vi ringrazio per l'eventuale Vostro aiuto.
Ciao

lbenaglia Profilo | Guru

>--
>-- START SCRIPT SQL
>--
>CREATE TABLE Utenti
>( username varchar (50), idRuolo Long, passw varchar (50) );
>
>ALTER TABLE Utenti ADD CONSTRAINT FK_Utenti_Ruoli FOREIGN KEY
>(idRuolo) REFERENCES Ruoli (id ) [ON UPDATE CASCADE ON DELETE
>CASCADE];
>--
>-- END SCRIPT SQL
>--
>
>L'Alter in ACCESS viene eseguita senza dare messaggi di errore
>o warning, ma se vado a vedere la relazione i due baffi non ci
>sono!!

Ciao dilaora,

hai provato a rimuovere quelle parentesi quadre?

ALTER TABLE Utenti ADD CONSTRAINT FK_Utenti_Ruoli FOREIGN KEY (idRuolo) REFERENCES Ruoli (id) ON UPDATE CASCADE ON DELETE CASCADE;

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Ciao Lorenzo, grazie per il tuo intervento...

Se provo a togliere le parentesi quadre mi da "errore di sintassi nella preposizione CONSTRAINT" selezionandomi la parola UPDATE...

lbenaglia Profilo | Guru

>Se provo a togliere le parentesi quadre mi da "errore di sintassi
>nella preposizione CONSTRAINT" selezionandomi la parola UPDATE...

Mmmmm... molto strano, eppure la sintassi che hai utilizzato è corretta:
http://office.microsoft.com/en-us/access/HA012314371033.aspx?pid=CH100728991033

Prova ad allegare in un nuovo messaggio il file .mdb compresso in formato zip.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Si avevo già dato un'occhiata all'articolo che mi hai indicato... ma il risultato non cambia aimè.

Ti allego il file db di esempio, troverai l'alter salvata in queries.

Ciao e Grazie



lbenaglia Profilo | Guru

>Si avevo già dato un'occhiata all'articolo che mi hai indicato...
>ma il risultato non cambia aimè.
>
>Ti allego il file db di esempio, troverai l'alter salvata in
>queries.

Allora, la questione è molto simpatica
Facendo una ricerca nella Knowledge Base ho trovato questo articolo:

"How to use common Data Definition Language (DDL) SQL statements for the Jet database engine"
http://support.microsoft.com/kb/180841/en-us

che recita: "Note: You cannot specify that you want "Cascade Updates" or "Cascade Deletes" with a relationship created using DDL. These features are available only when using the Microsoft DAO (Data Access Objects) interfaces via code or when using the Microsoft Access user interface."

Quindi DAO permette di definire operazioni cascade esclusivamente tramite il suo object model.
Per sfizio ho provato a scrivere un piccolo VB Script che utilizza ADO e l'OLEDB Provider di Jet 4.0 per connettersi al db, eseguendo il comando ALTER TABLE e, sorpresa, tutto ha funzionato alla perfezione:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Boh, sinceramente sono un po' perplesso, la documentazione ufficiale di Access recita: "Note: The Microsoft Jet database engine does not support the use of CONSTRAINT, or any of the data definition language (DDL) statements, with non-Microsoft Jet databases. Use the DAO Create methods instead."

In realtà abbiamo visto che il limite non è tanto di JET piuttosto di DAO, dato che ADO con l'OLEDB Provider di Jet 4.0 utilizza appunto Microsoft Jet...

>Ciao e Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Uè Lorenzo ... non ti dico + grazie altrimenti rischio di essere troppo ripetitivo...
javascript:ins('ctl00_Content_ctl00_txtBody','')

Lo scorcio di codice che mi hai gentilmente postato è in realtà quello che faccio io (cavolo, ma a me non ridà!) ... dalla applicazione.

Forse l'unica differenza che noto è nella connessione perche tu utilizzi il CreateObject("ADODB.Connection") io faccio una cosa del genere per aprire la connessione:

With m_Connessione
If .State = adStateOpen Then .Close
.CursorLocation = adUseClient
.Provider = Provider
If Provider = "Microsoft.Jet.OLEDB.4.0" Then
.Properties.Item("Data Source").Value = PathDB
.Properties.Item("User ID").Value = Uid
.Properties.Item("Jet OLEDB:Database Password").Value = Pwd
.Properties.Item("Persist Security info").Value = "False"
End If

.Open
End With

Connettiti = True ' Siamo in una funzione

Praticamente lavoro a connessione aperta ed eseguo le istruzioni DDL presenti su un file esterno alla fine chiudo la connessione.

Potrebbe essere questo il motivo?
(Nel frattempo provo come hai fatto tu!)

Ciao (anzichè grazie) :)

lbenaglia Profilo | Guru

> With m_Connessione
Cos'è m_Connessione? Da qualche parte l'avrai istanziata...

>Praticamente lavoro a connessione aperta ed eseguo le istruzioni
>DDL presenti su un file esterno alla fine chiudo la connessione.
>
>Potrebbe essere questo il motivo?
No. Nel tuo pezzetto di codice non vedo il richiamo al metodo Execute.
Come sottometti i comandi T-SQL all'istanza?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Lorenzo ti sto facendo lavorare ... se continuiamo cosi mi sa che mi mandi la Fattura vero? :)

Ma le CREATE le fa non credo sia un problema di EXECUTE, e cmq lo richiamo in m_MioDBAdo.UpdateTable ...


Faccio questo in un metodo VB6 (aimè!! preferivo c# o anche VB.net ma mi impogono di lavorar cosi :( ):

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

lbenaglia Profilo | Guru

>m_MioDBAdo.UpdateTable (RigaLetta) '> qui ci sta quello che
>dici tu! m_Connessione.Execute(CommandText)

Eh, allora deve andare
Non mi hai ancora detto cos'è m_Connessione... dove la dichiari e la istanzi?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Ma sei un fulmine!

Private m_Connessione As New ADODB.Connection

lbenaglia Profilo | Guru

>Private m_Connessione As New ADODB.Connection
Ripeto, allora deve andare
Per sfizio, esegui il VBS che ti ho proposto e vedi se ti funziona....
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Porca paletta!!!

Se lo eseguo come mi hai detto tu, da un file VBS va!

lbenaglia Profilo | Guru

>Se lo eseguo come mi hai detto tu, da un file VBS va!
Ecco, ora debugga

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Debuggare cosa?

Vanno entrambi bene... piuttosto provo a connettermi come mi hai fatto vedere tu ... con il CreateObject ... che ne dici?

lbenaglia Profilo | Guru

>Debuggare cosa?
>
>Vanno entrambi bene...
Scusa, ma continui ad affermare che la tua procedura non è in grado di generare le foreign key con operazioni cascade....

>piuttosto provo a connettermi come mi
>hai fatto vedere tu ... con il CreateObject ... che ne dici?
Dico che non cambia niente. In VBScript sono costretto ad utilizzare il late binding, mentre in VB6 puoi tranquillamente usare l'early binding, anche se eviterei di definire una variabile oggetto specificando New Classe dato che questo comporterà un inutile check di esistenza dell'oggetto prima di ogni chiamata a proprietà/metodi.
Piuttosto definirei la variabile a livello di modulo, la istanzierei nell'evento Initialize e la distruggerei esplicitamente nell'evento Terminate della classe.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

Va bene nel senso che non restituisce errore ... la foreign key viene generata ma senza le clausole di aggiornamento ed inserimento a cascata ...

Scusa ma non capisco con il debug come faccio a capire la soluzione ... mi entra nel metodo execute e mi esce correttamente, è tutto ok...

Ok.. per la connessione come non detto... molto prezioso il tuo consiglio grazie

lbenaglia Profilo | Guru

>Va bene nel senso che non restituisce errore ... la foreign key
>viene generata ma senza le clausole di aggiornamento ed inserimento
>a cascata ...
Hai tolto le fatidiche parentesi quadre?

>Scusa ma non capisco con il debug come faccio a capire la soluzione
>... mi entra nel metodo execute e mi esce correttamente, è tutto
>ok...
Prova a mettere un breakpoint sulla m_Connessione.Execute e posta il comando SQL di ALTER TABLE che stai per eseguire...

>Ok.. per la connessione come non detto... molto prezioso il tuo
>consiglio grazie
Di nulla.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

dilaora Profilo | Newbie

- se metto le parentesi quadre nel VBS mi va in errore quindi da li le tolgo
- se non le metto nel file che leggo nell'applicazione mi va in errore, quindi le metto

Un bel casino!

Ti faccio sapere!

dilaora Profilo | Newbie

o pebbacco!!

In debug ... step by step funge ... ora sono + confuso di prima ... ci lavoro un po' su e poi ti faccio sapere.

dilaora Profilo | Newbie

Lorenzo, ora va ... bah!!!

Non saprei dirti dove sbagliavo parentesi e non ho fatto tutte le prove del caso, boo!

Cmq grazie infinite per la tua infinita disponibilità.

Ciao
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5