Contrainte de colonne de bits SQL Server, 1 ligne = 1, tous les autres 0

J'ai un bit IsDefault colonne bit IsDefault . Une seule ligne de données dans la table peut avoir cette colonne bit définie sur 1 , toutes les autres doivent être 0 .

Comment puis-je appliquer cela?

Toutes les versions:

  • Déclencheur
  • Vue indexée
  • Proc stocké (par exemple test sur écriture)

SQL Server 2008: un index filtré

 CREATE UNIQUE INDEX IX_foo ON bar (MyBitCol) WHERE MyBitCol = 1 

En supposant que votre PK est une colonne numérique unique, vous pouvez append une colonne calculée à votre table:

 ALTER TABLE YourTable ADD IsDefaultCheck AS CASE IsDefault WHEN 1 THEN -1 WHEN 0 THEN YourPK END 

Créez ensuite un index unique sur la colonne calculée.

 CREATE UNIQUE INDEX IX_DefaultCheck ON YourTable(IsDefaultCheck) 

Je pense que le triggersur est la meilleure idée si vous voulez changer l'ancien logging par défaut à 0 quand vous insérez / mettez à jour un nouveau et si vous voulez vous assurer qu'un logging a toujours cette valeur (ie si vous supprimez l'logging avec la valeur vous l'atsortingbueriez à un logging différent). Vous devriez décider des règles pour le faire. Ces triggersurs peuvent être difficiles car vous devez comptabiliser plusieurs loggings dans les tables insérées et supprimées. Donc, si 3 loggings dans un lot essaient de mettre à jour pour devenir l'logging par défaut, lequel gagne?

Si vous voulez vous assurer que l'logging par défaut ne change jamais quand quelqu'un d'autre essaie de le changer, l'index filtré est une bonne idée.

Vous pouvez appliquer un triggersur Au lieu d'Insert et vérifier la valeur à mesure qu'elle arrive.

 Create Trigger TRG_MyTrigger on MyTable Instead of Insert as Begin --Check to see if the row is marked as active.... If Exists(Select * from inserted where IsDefault= 1) Begin Update Table Set IsDefault=0 where ID= (select ID from inserted); insert into Table(Columns) select Columns from inserted End End 

Vous pouvez également appliquer une contrainte unique sur la colonne.

La réponse acceptée à la question ci-dessous est à la fois intéressante et pertinente:

Contrainte pour un seul logging marqué par défaut

"Mais les gens sérieux relationnels vous diront que cette information devrait juste être dans une autre table."

Avoir une table séparée de 1 rangée qui vous indique quel logging est 'par défaut'. Anon a abordé cela dans son commentaire.

Je pense que c'est la meilleure approche – simple, propre et ne nécessite pas une solution ésotérique «intelligente» sujette à des erreurs ou à un malentendu plus tard. Vous pouvez même supprimer la colonne IsDefualt .