Mon développeur prétend que cela peut être réalisé avec une contrainte de vérification placé sur la table.
SQL Server ne pas directement ** sous-requêtes de soutien en CHECK
contraintes (une exigence pour SQL-92 complète, seul SQL Server est compatible avec niveau d'entrée SQL-92, d'une manière générale). Bien qu'il y ait certainement de meilleurs moyens d'imposer cette contrainte dans SQL Server, il est possible de réaliser une contrainte pure et simple en utilisant une contrainte CHECK
au niveau de la ligne et une contrainte UNIQUE
par exemple. voici une façon:
CREATE TABLE YourStuff
(
key_col INTEGER NOT NULL UNIQUE,
Various_Columns VARCHAR(8) NOT NULL,
Flag CHAR(1) DEFAULT 'F' NOT NULL
CHECK (Flag IN ('F', 'T')),
Flag_key INTEGER UNIQUE,
CHECK (
(Flag = 'F' AND Flag_key = key_col)
OR
(Flag = 'T' AND Flag_key = NULL)
)
);
La question ici est que vous aurez besoin de maintenir les valeurs de colonne Flag_key
« manuellement ». Remplacement de la colonne + CHECK
avec une colonne calculée signifierait que les valeurs sont maintenues automatiquement:
CREATE TABLE YourStuff
(
key_col INTEGER NOT NULL UNIQUE,
Various_Columns VARCHAR(8) NOT NULL,
Flag CHAR(1) DEFAULT 'F' NOT NULL
CHECK (Flag IN ('F', 'T')),
Flag_key AS (
CASE WHEN Flag = 'F' THEN key_col
ELSE NULL END
),
UNIQUE (Flag_key)
);
** Bien que SQL Server ne directement sous-requêtes de soutien à CHECK
contraintes, il existe une solution dans certains en utilisant une fonction définie par l'utilisateur (UDF)
CREATE FUNCTION dbo.CountTFlags()
RETURNS INTEGER
AS
BEGIN
DECLARE @return INTEGER;
SET @return = (
SELECT COUNT(*)
FROM YourStuff
WHERE Flag = 'T'
);
RETURN @return;
END;
CREATE TABLE YourStuff
(
key_col INTEGER NOT NULL UNIQUE,
Various_Columns VARCHAR(8) NOT NULL,
Flag CHAR(1) DEFAULT 'F' NOT NULL
CHECK (Flag IN ('F', 'T')),
CHECK (1 >= dbo.CountTFlags())
);
Notez que l'approche UDF ne fonctionnera pas dans tous les cas et que la prudence est requise. Le point important est que les fonctions UDF seront évaluées pour chaque ligne affectée (plutôt que pour l'instruction SQL ou le niveau de transaction, comme vous pouvez vous y attendre). Dans ce cas, la contrainte doit être vraie pour chaque ligne affectée et donc - je pense! -- c'est sûr. Pour plus de détails, voir Trouble with CHECK Constraints by David Portas.
Personnellement, je voudrais simplement utiliser une deuxième table pour modéliser Flag
, qui ne concernent que les clés et une clé étrangère par exemple
CREATE TABLE YourStuff
(
key_col INTEGER NOT NULL UNIQUE,
Various_Columns VARCHAR(8) NOT NULL
);
CREATE TABLE YourStuffFlag
(
key_col INTEGER NOT NULL UNIQUE
REFERENCES YourStuff (key_col)
);
Est table [ma] sous forme normale?
Vous devriez en visant la forme normale cinquième (5NF). Si vous avez réalisé cela dépend de la conception de Various_Columns
. Je ne crois pas que votre Flag
tombe la volaille des exigences pour 5NF et je ne vois aucune mise à jour, supprimer ou insérer des anomalies (qui est le point de normalisation, mais une conception 5NF peut encore présenter des anomalies). Cela dit, pour changer la ligne qui obtient le flag
attibute, ma conception à deux tables nécessite une seule instruction UPDATE
alors que votre conception de table unique en nécessite deux;)
Quelle version de SQL Server, s'il vous plaît? – gbn
Actuellement, Microsoft SQL Server 2005 – DACN
Juste au cas où il s'agit d'une liste de 'réponses' à une 'questions' vous pouvez simplement enregistrer la bonne réponse avec la question et toutes les fausses réponses dans une table. Une seule vraie réponse non répétitive est directement liée à la clé primaire d'une question. Je pensais juste que je mentionnerais que le motif semblait familier. –