2010-08-11 7 views
2

J'ai une colonne qui doit contenir l'une des valeurs de 2 puissance n: 2,4,8,16,32 etc. Je veux appliquer cela au niveau du schéma de table - est il existe un moyen de spécifier une telle contrainte de colonne?Définition de la contrainte de colonne sur une table (SQL Server)

Merci!

+0

Pouvez-vous expliquer pourquoi vous faites cela? – JonH

+0

Ok, il m'est juste venu à l'esprit que je devrais plutôt stocker n que 2 puissance n :) Affaire résolue! – Andrey

Répondre

4

Dans SQL Server:

ALTER TABLE [dbo].[PowerOfTwo] 
WITH CHECK ADD CONSTRAINT [CK_PowerOfTwo] 
CHECK ((log([Value])/log(2)=round(log([Value])/log(2), 0, 1))) 
1

Supposons que votre nom de colonne est N. Essayez quelque chose comme

CHECK(LOG(N)/LOG(2) = TRUNC(LOG(N)/LOG(2))) 

Le but est de vérifier que le logarithme binaire de la valeur N est un entier, ce qui voudrait dire que N était une puissance de 2. Non Assurez-vous que SQL Server prend en charge les fonctions LOG et TRUNC - remplacez-les par les noms appropriés si nécessaire. Edit: en relisant ceci, j'ai réalisé que l'arrondi pouvait causer un problème (j'ai oublié le deuxième commandement du point flottant, qui est: Tu ne compareras jamais les valeurs des virgules flottantes pour l'égalité!). OK, qu'en est-il

CHECK(ABS(LOG(N)/LOG(2) - TRUNC(LOG(N)/LOG(2))) < 0.00001) 

ou de remplacer n'importe quelle tolérance d'erreur que vous souhaitez pour le 0.00001.

Partagez et appréciez.

+0

Bon, merci! – Andrey

0

Créer une vérification de la colonne:

CHECK (column_name IN (2, 4, 8, 16, 32, ..., 2147483648)) 
+0

Raisons pour downvoting quelqu'un? – GSerg

+1

Êtes-vous sérieux? – Andrey

+0

Oui je suis sérieux. En quoi cette réponse est-elle conceptuellement différente de la réponse acceptée? Oui, j'ai pensé qu'il serait préférable d'utiliser une simple liste de valeurs, car il y en a peu, plutôt que d'appeler 'log' 4 fois, mais à part cette différence (non pertinente), il n'y a rien d'autre. Ou insinuez-vous que votre colonne est réellement de type 'double', pas' int'? Dans ce cas, la réponse acceptée est également fausse, car il y a une précision à virgule flottante finie à cause de laquelle la comparaison sera vraisemblablement moins vraie que prévu. – GSerg

2

comment sur la définition de la colonne à N. puis toutes les utilisations de cette colonne seraient 2^n, par définition, au lieu de contrainte. Sinon, vous pouvez mettre en place une logique de déclenchement pour valider chaque valeur lors de sa saisie ou de sa mise à jour.

+0

Je l'ai déjà compris il y a quelques minutes :) Je vais vous mettre de côté quand même car c'est une bonne idée – Andrey

5

voler sans vergogne de this answer vous pouvez utiliser pour faire des opérations au niveau du bit cette jolie efficacement.

ALTER TABLE tablename ADD CONSTRAINT 
    ckname CHECK (colName > 0 AND (colName & (colName - 1) =0)) 
+0

Mais pas aussi efficacement que la réponse de Randy ... –