[SQL server 2005] Clausola constraint ON DELETE/ON UPDATE

martedì 11 agosto 2009 - 17.27

symonx80 Profilo | Junior Member

Ciao, ho due tabelle

UTENTE(CF,USER,PSW)
TESSERA(NUM_TESSERA,CF)

HO creato il mio db ma quando provo a cancellare un utente che possiede una tessera mi viene segnalato errore di integrità referenziale anche se io ho impostato che nel delete di un utente non si debba fare nulla. Insomma io voglio che le mie tessere rimangano anche se elimino tutti gli utenti.. Il mio db l'ho creato con il seguente script, cosa sbaglio? Grazie

CREATE TABLE UTENTE
(
CF varchar(16) NOT NULL
USER varchar(50) NOT NULL
PSW varchar(50 ) NOT NULL
)
go


ALTER TABLE TB_UTENTE
ADD CONSTRAINT XPKUTENTE PRIMARY KEY NONCLUSTERED (CF ASC)
go



CREATE TABLE TESSERA
(
NUM_TESSERA INT NOT NULL
CF varchar(16) NOT NULL
)
go


ALTER TABLE TESSERA
ADD CONSTRAINT XPKTESSERA PRIMARY KEY NONCLUSTERED (NUM_TESSERA ASC, CF ASC)
go


ALTER TABLE TESSERA
ADD CONSTRAINT TES_UTE FOREIGN KEY (CF) REFERENCES UTENTE(CF)
ON UPDATE CASCADE
go

lbenaglia Profilo | Guru

>ALTER TABLE TESSERA
> ADD CONSTRAINT TES_UTE FOREIGN KEY (CF) REFERENCES UTENTE(CF)
> ON UPDATE CASCADE
>
>HO creato il mio db ma quando provo a cancellare un utente che
>possiede una tessera mi viene segnalato errore di integrità referenziale
>anche se io ho impostato che nel delete di un utente non si debba
>fare nulla.

Ciao Simone,

Tu semplicemente hai definito un constraint di FK specificando le operazioni CASCADE solo in caso di UPDATE.
Il constraint (che tradotto significa vincolo) di FK serve a garantire l'integrità referenziale tra due tabelle, quindi evita che possano esistere dei "figli" orfani di "padre" (ovvero non possono esistere righe nella parte molti della relationship non relazionate ad alcuna riga nella parte 1 della relationship).

>Insomma io voglio che le mie tessere rimangano anche
>se elimino tutti gli utenti.
Allora devi dirlo e per farlo hai 2 modi:

1) Valorizzare a NULL la colonna CF;
2) Modificare la colonna CF associandola ad utente differente da quello eliminato ma comunque presente nella tabella Utenti.

Nel tuo caso dato che la colonna CF fa parte della PK di TESSERA (tra l'altro non ne capisco il motivo, a meno di avere numeri di tessera duplicati) non può assumere il valore NULL, quindi puoi adottare solo la seconda soluzione:

USE tempdb; CREATE TABLE dbo.UTENTE ( CF varchar(16) NOT NULL, [USER] varchar(50) NOT NULL, PSW varchar(50) NOT NULL ); ALTER TABLE dbo.UTENTE ADD CONSTRAINT PK_UTENTE PRIMARY KEY NONCLUSTERED (CF ASC); CREATE TABLE dbo.TESSERA ( NUM_TESSERA int NOT NULL, CF varchar(16) NOT NULL DEFAULT 'yyyyyyyyyyyyyyyy' ); ALTER TABLE dbo.TESSERA ADD CONSTRAINT PK_TESSERA PRIMARY KEY NONCLUSTERED (NUM_TESSERA ASC, CF ASC); ALTER TABLE dbo.TESSERA ADD CONSTRAINT TES_UTE FOREIGN KEY (CF) REFERENCES dbo.UTENTE(CF) ON UPDATE CASCADE ON DELETE SET DEFAULT; INSERT dbo.UTENTE VALUES ('xxxxxxxxxxxxxxxx', 'Lorenzo', 'Password') , ('yyyyyyyyyyyyyyyy', 'Simone', 'Password'); INSERT dbo.TESSERA VALUES (1, 'xxxxxxxxxxxxxxxx') , (2, 'xxxxxxxxxxxxxxxx') , (3, 'xxxxxxxxxxxxxxxx'); /* Elimino l'utente Lorenzo */ DELETE dbo.UTENTE WHERE [USER] = 'Lorenzo'; SELECT * FROM dbo.TESSERA; /* Output: NUM_TESSERA CF ----------- ---------------- 1 yyyyyyyyyyyyyyyy 2 yyyyyyyyyyyyyyyy 3 yyyyyyyyyyyyyyyy (3 row(s) affected) */ DROP TABLE dbo.TESSERA, dbo.UTENTE;

Per maggiori dettagli consulta il seguente paragrafo dei BOL:
http://msdn.microsoft.com/en-us/library/ms188066.aspx

> Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
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