2017-08-09 2 views
1

J'ai une base de données de jeu dans laquelle j'essaie de trouver des choses et qui a créé une table contenant une clé étrangère. Je veux limiter le nombre de fois qu'une valeur spécifique de cette autre table peut apparaître dans cette table. Je veux que la table 'locale' accepte n'importe quelle valeur de cette table étrangère, mais seulement jusqu'à un maximum de quatre fois. Je pense que cela peut être fait avec un déclencheur, mais j'aimerais savoir s'il existe une sorte de contrainte ou de vérification qui peut être placée pour appliquer cette règle. La raison en est que les objets que je décris peuvent avoir un maximum de quatre descripteurs associés et que je ne veux pas que quatre colonnes soient conservées dans la table principale, car chaque élément n'atteindra pas cette limite; en fait, je crois que la plupart n'en auront jamais deux.Façon de restreindre le nombre de fois qu'une valeur peut apparaître dans une table

+1

Trigger fera. Il existe d'autres options en utilisant une clé composite et en restreignant les valeurs dans la deuxième colonne. Mais dans ce cas, l'incrément de valeur dans la 2ème colonne doit être maintenu à la couche de gestion. – MKR

+0

Je suis d'accord avec le déclencheur. Vous pouvez mettre une contrainte de vérification sur la table qui appelle une fonction, mais ce n'est pas idéal. Vous pouvez également écrire une procédure stockée avec la logique. – squillman

Répondre

2

J'utiliserais une contrainte de vérification avec une fonction définie par l'utilisateur.
Il y a deux avantages de ce rapport à l'utilisation des déclencheurs:

  1. C'est ce que les contraintes de vérification sont conçus pour.
  2. L'utilisation de déclencheurs nécessiterait au lieu d'insert et au lieu de déclencheurs de mise à jour, ce qui entraînerait un code beaucoup plus long, plus difficile à écrire et à maintenir.

Voici un exemple rapide:

Créer une table de test:

CREATE TABLE Test 
(
    Col1 int 
) 
GO 

Créer la fonction de validation:

CREATE FUNCTION dbo.IsValueAllowed 
(
    @Value int 
) 
RETURNS bit 
AS 
BEGIN 

IF (SELECT COUNT(*) FROM Test WHERE Col1 = @Value) > 4 RETURN 0 

RETURN 1 

END 
GO 

Ajouter la contrainte de vérification à la table

ALTER TABLE Test 
    ADD CONSTRAINT ck_RestrictCol1 CHECK (dbo.IsValueAllowed(Col1) = 1) 
GO 

Tests:

INSERT INTO Test VALUES 
(1), (1), (1), (1), 
(2), (2), (2) 

INSERT INTO Test VALUES (2) 

SELECT * 
FROM Test 

INSERT INTO Test VALUES (1) -- This will fail with an error message: The INSERT statement conflicted with the CHECK constraint "ck_RestrictCol1" 

see a live demo on rextester.