Relazione doppia tra 2 tabelle e DELETE CASCADE

di il
2 risposte

Relazione doppia tra 2 tabelle e DELETE CASCADE

Ciao
Avrei un quesito sul delete di record in una determinata situazione visto che SSMS non mi lascia creare le relazioni per il delete in cascata.
La logica e' questa:
Nella tabella 1 ho un elenco recipienti
NomeRecipiente

Nella tabella 2 ho un elenco di quanti litri vengono trasferiti da un recipiente ad un altro
idLitriTransf
RecipienteDa
RecipienteA
Litri

La situazione potrebbe essere quindi questa:
Dal recipiente A verso 10 litri nel recipiente B
Dal recipiente B verso 5 litri nel recipiente C

I record della seconda tabella sarebbero quindi
1, A, B, 10
2, B, C, 5

Supponiamo ora che io voglia eliminare il recipiente B dalla tabella 1, quindi vorrei che anche i due record della tabella 2 vengano eliminati.
Dovrei quindi creare due relazioni entrambe con DELETE impostato a CASCADE
PK->FK
NomeRecipiente->RecipienteA
NomeRecipiente->RecipienteDa

Il problema e' che SQLSERVER mi lascia creare solo la prima relazione.
Quando tento di creare la seconda ricevo questo errore:
"L'introduzione del vincolo...può determinare la creazione di cicli o più percorsi di propagazione.
Specificare ON DELETE NO ACTION o ON UPDATE NO ACTION oppure modificare gli altri vincoli FOREIGN KEY."

Come dovrei quindi comportarmi per fare in modo che se dalla tabella 1 elimino un record, nella tabella 2 venga eliminato qualsiasi suo riferimento sia esso in un campo oppure in un altro?

Per ora sto usando una StoredProcedure ma preferivo risolvere il tutto solo con le relazioni impostate correttamente.

P.S. le tabelle appena descritte sono solo un esempio per rendere chiara la situazione

2 Risposte

  • Re: Relazione doppia tra 2 tabelle e DELETE CASCADE

    Salve,
    il problema e' complesso... vedi benissimo che il vincolo ha path multipli e proprio per questo motivo il database engine ti indica che "normalmente" non e' buona prassi agire in questo senso, e suggerisce appunto il workaround di impostare l'azione del CASCADE a NO ACTION, permettendo quindi la "sola definzione del vincolo" (prassi comunque corretta in modo da autodocumentare la relazione tra le entita', lasciando il vincolo "disabilitato"') e suggerendo altresi l'uso di altri modi di gestire la referential integrity dichiarativa, cosa che in questi casi avviene solitamente attraverso triggers, https://support.microsoft.com/en-us/help/321843/error-message-1785-occurs-when-you-create-a-foreign-key-constraint-tha

    il trigger consente infatti la completa autonomia in quanto conterra' (a tua cura) la logica completa del "path" che intendi seguire, quindi la logica la devi implementare direttamente, magari anche in "azioni sequenziali" dove l'ordine di esecuzione e' fondamentale, mentre il constraint lascia "nel dubbio" il motore relazionale, e non avendo altra logica implementata, non e' in grado di scegliere il path da seguire.

    l'uso di trigger ti consente la piu' completa liberta' e mantiene direttamente legato alla definizione DDL la soluzione del problema, ma anche l'uso di una stored procedure ovviamente fa al caso, tanto piu' che (ovviamente :D), dal punto di vista del dba, non sarebbe "buona cosa" dare accesso diretto agli sviluppatori alle base tables, preferendo quindi per l'accesso ai dati al solo utilizzo di stored procedures... sicuramente qui do adito all'apertura di un flame ed alla riapertura della relativa guerra di religione in corso tra dev e sys, ma tant'e' :D

    salutoni romagnoli
    --
    Andrea
  • Re: Relazione doppia tra 2 tabelle e DELETE CASCADE

    Intanto grazie mille
    Nel mentre aspettavo un feedback avevo provveduto a testare la cosa anche coi trigger. E funziona bene.
    Tempo fa pero' avevo fatto dei test con EntityFramework e C#, ed in altri contesti, i trigger mi creavano problemi.

    Dal punto di vista funzionale preferisco i trigger perche' sono li e non devo preoccuparmene.
    Vedremo in futuro se EF mi darà ancora dei problemi ed al caso passero' alle SP.

    Comunque, in questa situazione faccio sia da sys che da dev quindi pazienza per i flame

    Grazie
Devi accedere o registrarti per scrivere nel forum
2 risposte