Restreindre la colonne varchar () à des valeurs spécifiques?

94

Existe-t-il un moyen de spécifier, par exemple, 4 valeurs distinctes pour une colonne varchar dans MS SQL Server 2008?

Par exemple, j'ai besoin d'une colonne appelée Frequency (varchar) qui n'accepte que les valeurs possibles "Daily", "Weekly", "Monthly", "Yearly"

Est-ce possible de définir dans SQL Server Management Studio lors de la création de la table?

Adam
la source
5
S'il est prudent de supposer qu'il n'y aura plus de valeurs valides et qu'il y aura de nombreuses lignes dans le tableau, j'encode les valeurs possibles dans quelque chose de plus petit et plus rapide qu'un varchar ().
Wikser

Réponses:

127

Avez-vous déjà envisagé d'ajouter un check constraintsur cette colonne qui limiterait les valeurs? Quelque chose comme:

CREATE TABLE SomeTable
(
   Id int NOT NULL,
   Frequency varchar(200),
   CONSTRAINT chk_Frequency CHECK (Frequency IN ('Daily', 'Weekly', 'Monthly', 'Yearly'))
)
Ashish Gupta
la source
2
Merci - cela a très bien fonctionné. Un petit changement que j'ai dû faire cependant était que "Frequency IN ...." devait également être placé entre parenthèses. Le studio de serveur SQL ne l'aimait pas sans pour une raison quelconque.
Adam
1
Cette vérification de contrainte est-elle sensible à la casse?
RWendi
3
Je pense que vous avez manqué un coma après la 4ème ligneFrequency varchar(200)
BillOverFlow
RWendi - le classement par défaut de SQL Server est insensible à la casse, ce qui s'applique au niveau de la base de données. Plus d'informations ici stackoverflow.com/questions/1439485/…
jwoe
57

Vous voulez une contrainte de vérification .

Les contraintes CHECK déterminent les valeurs valides à partir d'une expression logique qui n'est pas basée sur les données d'une autre colonne. Par exemple, la plage de valeurs pour une colonne de salaire peut être limitée en créant une contrainte CHECK qui autorise uniquement les données comprises entre 15 000 USD et 100 000 USD. Cela empêche les salaires d'être saisis au-delà de l'échelle salariale normale.

Vous voulez quelque chose comme:

ALTER TABLE dbo.Table ADD CONSTRAINT CK_Table_Frequency
    CHECK (Frequency IN ('Daily', 'Weekly', 'Monthly', 'Yearly'))

Vous pouvez également implémenter des contraintes de vérification avec des fonctions scalaires, comme décrit dans le lien ci-dessus, ce que je préfère faire.

Michael Petrotta
la source
1
cette réponse était bonne aussi .. pourquoi ne pouvons-nous pas en accepter plus d'un !! :)
Adam
1
Oui, celui-ci est meilleur :), +1 pour cela
Owais Qureshi
11

Personnellement, je le coderais comme tinyint et:

  • Soit: changez-le en texte sur le client, vérifiez la contrainte entre 1 et 4
  • Ou: utilisez une table de consultation avec une clé étrangère

Les raisons:

  • Il faudra en moyenne 8 octets pour stocker le texte, 1 octet pour tinyint. Sur des millions de lignes, cela fera la différence.

  • Et la collation? «Daily» est-il le même que «DAILY»? Il faut des ressources pour faire ce genre de comparaison.

  • Enfin, que se passe-t-il si vous souhaitez ajouter "Toutes les deux semaines" ou "Toutes les heures"? Cela nécessite un changement de schéma lorsque vous pouvez simplement ajouter de nouvelles lignes à une table de recherche.

gbn
la source
5

Lorsque vous éditez une table
Clic droit -> Vérifier les contraintes -> Ajouter -> Tapez quelque chose comme Frequency IN ('Daily', 'Weekly', 'Monthly', 'Yearly')dans le champ d'expression et un bon nom de contrainte dans le champ (Nom).
Vous avez terminé.

Denis K
la source