web-dev-qa-db-fra.com

Une contrainte de vérification peut-elle être associée à une autre table?

Disons que j'ai une table appelée ProjectTimeSpan (ce que je n'ai pas fait, à titre d'exemple!) Contenant les colonnes StartDate et EndDate .

Et que j’ai une autre table appelée SubProjectTimeSpan , contenant également des colonnes nommées StartDate et EndDate , où je voudrais définir une contrainte de vérification rendant impossible la définition de StartDate et EndDate aux valeurs "extérieures" au ProjectTimeSpan.StartDate à ProjectTimeSpan.EndDate

Type de contrainte de vérification qui sait à propos de une autre tables valeurs ...

Est-ce possible?

26
Jack Johnstone

En réponse à votre commentaire sur la réponse de GSerg, voici un exemple de contrainte de vérification utilisant une fonction:

alter table YourTable
add constraint chk_CheckFunction
check (dbo.CheckFunction() = 1)

Où vous pouvez définir la fonction comme:

create function dbo.CheckFunction()
returns int
as begin
    return (select 1)
end

La fonction est autorisée à référencer d'autres tables.

38
Andomar

Vous pouvez créer une fonction définie par l'utilisateur qui effectue la vérification et renvoie 1 ou 0, puis créez une contrainte check, en fournissant l'ID de projet et les dates comme paramètres.

14
GSerg

Créez une clé composée de la clé de la table ProjectTimeSpan combinée aux colonnes StartDate et EndDate, puis utilisez cette clé composée comme référence de clé étrangère dans votre table SubProjectTimeSpan. Cela vous donnera la possibilité d'écrire les contraintes CHECK de niveau ligne nécessaires dans la table SubProjectTimeSpan, par exemple. 

CREATE TABLE ProjectTimeSpan 
(
 project_ID INTEGER NOT NULL UNIQUE, -- key
 StartDate DATE NOT NULL, 
 EndDate DATE NOT NULL, 
 CHECK (StartDate < EndDate), 
 UNIQUE (project_ID, StartDate, EndDate) -- compound key
 -- other project columns here...
);

CREATE TABLE SubProjectTimeSpan 
(
 project_ID INTEGER NOT NULL, 
 StartDate DATE NOT NULL, 
 EndDate DATE NOT NULL, 
 FOREIGN KEY (project_ID, StartDate, EndDate)
    REFERENCES ProjectTimeSpan (project_ID, StartDate, EndDate)
    ON DELETE CASCADE
    ON UPDATE CASCADE, 
 sub_StartDate DATE NOT NULL, 
 sub_EndDate DATE NOT NULL, 
 CHECK (sub_StartDate < sub_EndDate),
 CHECK (StartDate <= sub_StartDate), -- sub project can't start before main project
 CHECK (sub_EndDate <= EndDate)      -- sub project can't end after main project
 -- other sub project columns here...
);
6
onedaywhen

Vous devez ajouter une contrainte sur la table parent et la table enfants car le sous-projet ne peut pas être en dehors de la plage de projet, mais la plage de projet ne peut pas également sortir de tout le sous-projet.

Dans ce genre de situation, vous devez reporter la vérification de la contrainte sur un niveau supérieur (service Web, application) avec une transaction pour vous assurer que vos données sont dans un état valide après plusieurs requêtes sur les deux tables!

0
Marco Guignard