J'ai une table client qui a une relation un à plusieurs avec une table adresse. Je veux contraindre la base de données pour qu'un client avec auront toujours une (et une seule) adresse par défaut.
Je peux facilement ajouter une contrainte pour m'assurer qu'il n'y a jamais qu'une seule adresse par défaut pour chaque client. J'ai cependant du mal à savoir comment appliquer une contrainte qui garantisse qu'une adresse soit toujours marquée comme adresse par défaut.
En résumé :
- Un client n'est pas tenu d'avoir une adresse.
- Si un client a des adresses, il doit y avoir une adresse par défaut.
- Il ne peut y avoir qu'une seule adresse par défaut par client.
Voici un exemple du problème et quelques tests "unitaires". J'utilise une table de liens pour relier les clients et les adresses.
CREATE TABLE Customer
(
Id INT PRIMARY KEY,
Name VARCHAR(100) NOT NULL
)
CREATE TABLE [Address]
(
Id INT PRIMARY KEY,
Address VARCHAR(500) NOT NULL
)
CREATE TABLE CustAddress
(
CustomerId INT,
AddressId INT,
[Default] BIT NOT NULL,
FOREIGN KEY (CustomerId) REFERENCES Customer(Id),
FOREIGN KEY (AddressId) REFERENCES [Address](Id)
)
INSERT INTO Customer VALUES (1, 'Mr Greedy')
INSERT INTO [Address] VALUES (1, 'Roly-Poly House, Fatland')
INSERT INTO [Address] VALUES (2, 'Giant Cottage, A Cave')
-- Should succeed
INSERT INTO CustAddress VALUES (1, 1, 1)
INSERT INTO CustAddress VALUES (1, 2, 0)
DELETE FROM CustAddress
-- Should fail as no default address set
INSERT INTO CustAddress VALUES (1, 1, 0)
DELETE FROM CustAddress
-- Should fail as we end up with no defualt address set
INSERT INTO CustAddress VALUES (1, 1, 1)
INSERT INTO CustAddress VALUES (1, 2, 0)
UPDATE CustAddress SET [Default] = 0 WHERE CustomerId = 1 AND AddressId = 1
DELETE FROM CustAddress
-- Should fail as we end up with no defualt address set
INSERT INTO CustAddress VALUES (1, 1, 1)
INSERT INTO CustAddress VALUES (1, 2, 0)
DELETE FROM CustAddress WHERE CustomerId = 1 AND AddressId = 1