Struttura tabelle errore: Unable to create relationship...

mercoledì 29 agosto 2012 - 11.09
Tag Elenco Tags  SQL Server 2008 R2  |  SQL Server 2008

andrestu Profilo | Expert


822x633 96Kb


come potete vedere nell'immagine inserita ho creato un semplice struttura tabellare con la seguente configurazione (nell'immagine ho schiarito volutamente le parti non interressate alla questione):

tabella ARCMS_GeoLocalità colonna [id] impostata come primary key
tabella ARCMS_Utente colonna [idLocalitàResidenza] impostata relazione foreign key con primary key della tabella ARCMS_GeoLocalità
tabella ARCMS_Utente colonna [idLocalitàNascita] impostata relazione foreign key con primary key della tabella ARCMS_GeoLocalità

quindi due foreign key nella stessa tabella relazionate alla stessa primary key, e fin qui tutto ok.
A questo punto vorrei fare in modo che se nella tabella ARCMS_GeoLocalità elimino un record, venga in automatico impostato valore null nei relativi dati della tabella ARCMS_Utente ( [idLocalitàResidenza] e [idLocalitàNascita] ). Stessa cosa in caso di modifica, cioè vorrei che le modifiche vengano riflesse nella tabella ARCMS_Utente.
Per fare questo pensavo di impostare la proprietà della relazione Delete Rule su Set Null e Update Rule su Cascade solo che avendo due foreign key ricevo un errore di questo tipo:

- Unable to create relationship 'FK_ARCMS_Utente_ARCMS_GeoLocalità1'.
Introducing FOREIGN KEY constraint 'FK_ARCMS_Utente_ARCMS_GeoLocalità1' on table 'ARCMS_Utente' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.



Andrea Restucci - Web Developer

alx_81 Profilo | Guru

>- Unable to create relationship 'FK_ARCMS_Utente_ARCMS_GeoLocalità1'.
>Introducing FOREIGN KEY constraint 'FK_ARCMS_Utente_ARCMS_GeoLocalità1'
>on table 'ARCMS_Utente' may cause cycles or multiple cascade
>paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or
>modify other FOREIGN KEY constraints.
ciao,
c'è poco da dire.. rischi la ridondanza ciclica.. quindi non te lo fa fare.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.microsoft.com/profiles/Alessandro.Alpi

andrestu Profilo | Expert

si ok ma la soluzione in questi casi qual'è?
quali sono gli "strumenti" che si possono utilizzare per ovviare a questo problema a parte strutturare la tabella in modo diverso, in questo caso bisognerebbe eliminare la relazione e copiare il dato come testo, con il risultato che al posto di 2 colonne int avrò 6 colonne nvarchar [comune-residenza provincia-residenza regione-residenza comune-nascita provincia-nascita regione-nascita], mmm non mi sembra una grande soluzione...

alx_81 Profilo | Guru

>si ok ma la soluzione in questi casi qual'è?
Ciao, scusa il ritardo nella risposta ma richiedeva un po' di attenzione in più.

>quali sono gli "strumenti" che si possono utilizzare per ovviare
>a questo problema a parte strutturare la tabella in modo diverso,
>in questo caso bisognerebbe eliminare la relazione e copiare
>il dato come testo, con il risultato che al posto di 2 colonne
>int avrò 6 colonne nvarchar [comune-residenza provincia-residenza
>regione-residenza comune-nascita provincia-nascita regione-nascita],
>mmm non mi sembra una grande soluzione...
SQL Server non ti consente di fare questa cosa perchè quando trova un conflitto probabile previene l'operazione. E questo è un dato di fatto che non è possibile evitare.
Ovviamente puoi cambiare struttura o design, ma questo porterebbe comunque un refactor non così leggero come può sembrare.
Ragion per cui mi viene da consigliarti l'utilizzo di trigger e quindi gestire tu, tramite trigger le operazioni in cascata.

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.microsoft.com/profiles/Alessandro.Alpi

andrestu Profilo | Expert

> Ciao, scusa il ritardo nella risposta ma richiedeva un po' di attenzione in più.
no problem tanto il sito in questione è già in produzione quindi rimarrà tutto così comè, non è un problema bloccante, ho postato questo quesito solo per capire meglio in futuro come risolvere il "quiz" visto che non è la prima volta che incappo in questa problematica (se così si può chiamare)

> Ovviamente puoi cambiare struttura o design, ma questo porterebbe comunque un refactor non così leggero come può sembrare.
ma sinceramente non vedo altre strade a parte l'utilizzo di trigger (come da tuo suggerimento) o il NON utilizzo delle chiavi, il fatto è che se consideriamo la questione da un punto di vista più astratto senza entrare nello specifico si riduce tutto ad una definizione:
Non si possono inserire due foreign key nella stessa tabella X che si relazionano alla stessa primary key di una tabella Y, o meglio lo si può fare ma di certo non si possono sfruttare su quel dato i meccanismo di aggiornamento o eliminazione a cascata...
cioè alla fine penso che non ci sono design alternativi a quello che ho fatto io, sicuramente non sarò un asso nel progettare database ma credo che il meccanismo delle relazioni tra primary key e foreign key è quello e più di tanto non si può fare.
Per quanto riguarda i trigger non li ho mai utilizzati, sono affidabili?
è difficile usarli?
da quanto ho capito sono delle procedure che si attivano quando accade un certo evento giusto?


Andrea Restucci - Web Developer

alx_81 Profilo | Guru

>Non si possono inserire due foreign key nella stessa tabella
>X che si relazionano alla stessa primary key di una tabella Y,
>o meglio lo si può fare ma di certo non si possono sfruttare
>su quel dato i meccanismo di aggiornamento o eliminazione a cascata...
il che è corretto, perchè stai partendo dallo stesso padre. A quanto pare qualche dbms fa fare questa operazione, con il rovescio della medaglia che ti perdi delle info in certi casi.

>cioè alla fine penso che non ci sono design alternativi a quello
>che ho fatto io, sicuramente non sarò un asso nel progettare
>database ma credo che il meccanismo delle relazioni tra primary
>key e foreign key è quello e più di tanto non si può fare.
Su questo non sindaco, non conoscendo la tua struttura dati.

>Per quanto riguarda i trigger non li ho mai utilizzati, sono affidabili?
certo

>è difficile usarli?
no, per nulla, sono semplici eventi che vengono lanciati dopo una transazione o nella transazione in base a tipi di operazioni che vengono eseguite nelle tabelle (le comuni CRUD).
Puoi anche farli DDL, ma a te in questo caso non servono.

Fai solo attenzione perchè:
a -- sono piuttosto nascosti
b -- implicano un ingrandimento della transazione
c -- rischi di mettere troppe cose dentro alla gestione

cerca sempre di fare il meno possibile e con le logiche più semplci possibili, poichè il trigger viene lanciato, senza interessarsi del chi ha scatenato l'evento.
In alternativa, forse meno modulare, puoi mettere le logiche dentro a stored procedure.

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.microsoft.com/profiles/Alessandro.Alpi

andrestu Profilo | Expert

>In alternativa, forse meno modulare, puoi mettere le logiche dentro a stored procedure

be però in questo caso l'operazione non sarebbe automatizzata giusto? nel senso che devo lanciare manualmente (tramite c#) la SP al completamento di un operazione di eliminazione o aggiornamento. oppure si possono utilizzarle in altra modalità a me sconosciuta ?

Andrea Restucci - Web Developer

alx_81 Profilo | Guru

>be però in questo caso l'operazione non sarebbe automatizzata
>giusto? nel senso che devo lanciare manualmente (tramite c#)
>la SP al completamento di un operazione di eliminazione o aggiornamento.
>oppure si possono utilizzarle in altra modalità a me sconosciuta?
Non proprio, io intendo che la stored procedure fa sia la delete/update sia la gestione dell'evento.
Alla fine, puoi anche pensare di fare una sp per la gestione dell'evento (riutilizzabile) e ogni stored procedure che gestisce crud su quell'entità, chiama, modularmente, l'altra sp che gestisce l'evento.
Così, se devi cambiare, cambi un solo posto. Di certo tuttavia, non è automatizzato. Ma è può essere più controllabile dal dev direttamente.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.microsoft.com/profiles/Alessandro.Alpi
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-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5