Nous ne stockons plus jamais les énumérations sous forme de valeurs ordinales numériques; cela rend le débogage et le support beaucoup trop difficiles. Nous stockons la valeur d'énumération réelle convertie en chaîne:
public enum Suit { Spade, Heart, Diamond, Club }
Suit theSuit = Suit.Heart;
szQuery = "INSERT INTO Customers (Name, Suit) " +
"VALUES ('Ian Boyd', %s)".format(theSuit.name());
puis relisez avec:
Suit theSuit = Suit.valueOf(reader["Suit"]);
Le problème était dans le passé de regarder Enterprise Manager et d'essayer de déchiffrer:
Name Suit
================== ==========
Shelby Jackson 2
Ian Boyd 1
versets
Name Suit
================== ==========
Shelby Jackson Diamond
Ian Boyd Heart
ce dernier est beaucoup plus facile. Le premier nécessitait d'obtenir le code source et de trouver les valeurs numériques affectées aux membres de l'énumération.
Oui, cela prend plus de place, mais les noms des membres de l'énumération sont courts et les disques durs sont bon marché, et cela vaut bien plus la peine d'aider lorsque vous rencontrez un problème.
De plus, si vous utilisez des valeurs numériques, vous y êtes lié. Vous ne pouvez pas insérer ou réorganiser correctement les membres sans avoir à forcer les anciennes valeurs numériques. Par exemple, en modifiant l'énumération Suit en:
public enum Suit { Unknown, Heart, Club, Diamond, Spade }
devrait devenir:
public enum Suit {
Unknown = 4,
Heart = 1,
Club = 3,
Diamond = 2,
Spade = 0 }
afin de conserver les valeurs numériques héritées stockées dans la base de données.
Comment les trier dans la base de données
La question se pose: disons que je voulais ordonner les valeurs. Certaines personnes peuvent vouloir les trier par la valeur ordinale de l'énumération. Bien sûr, ordonner les cartes en fonction de la valeur numérique de l'énumération n'a pas de sens:
SELECT Suit FROM Cards
ORDER BY SuitID; --where SuitID is integer value(4,1,3,2,0)
Suit
------
Spade
Heart
Diamond
Club
Unknown
Ce n'est pas l'ordre que nous voulons - nous les voulons dans l'ordre d'énumération:
SELECT Suit FROM Cards
ORDER BY CASE SuitID OF
WHEN 4 THEN 0 --Unknown first
WHEN 1 THEN 1 --Heart
WHEN 3 THEN 2 --Club
WHEN 2 THEN 3 --Diamond
WHEN 0 THEN 4 --Spade
ELSE 999 END
Le même travail qui est requis si vous enregistrez des valeurs entières est requis si vous enregistrez des chaînes:
SELECT Suit FROM Cards
ORDER BY Suit; --where Suit is an enum name
Suit
-------
Club
Diamond
Heart
Spade
Unknown
Mais ce n'est pas l'ordre que nous voulons - nous les voulons dans l'ordre d'énumération:
SELECT Suit FROM Cards
ORDER BY CASE Suit OF
WHEN 'Unknown' THEN 0
WHEN 'Heart' THEN 1
WHEN 'Club' THEN 2
WHEN 'Diamond' THEN 3
WHEN 'Space' THEN 4
ELSE 999 END
Mon avis est que ce type de classement appartient à l'interface utilisateur. Si vous triez des éléments en fonction de leur valeur d'énumération: vous faites quelque chose de mal.
Mais si vous vouliez vraiment faire cela, je créerais une Suits
table de dimension:
| Suit | SuitID | Rank | Color |
|------------|--------------|---------------|--------|
| Unknown | 4 | 0 | NULL |
| Heart | 1 | 1 | Red |
| Club | 3 | 2 | Black |
| Diamond | 2 | 3 | Red |
| Spade | 0 | 4 | Black |
De cette façon, lorsque vous souhaitez modifier vos cartes pour utiliser Kissing Kings New Deck Order, vous pouvez le modifier à des fins d'affichage sans perdre toutes vos données:
| Suit | SuitID | Rank | Color | CardOrder |
|------------|--------------|---------------|--------|-----------|
| Unknown | 4 | 0 | NULL | NULL |
| Spade | 0 | 1 | Black | 1 |
| Diamond | 2 | 2 | Red | 1 |
| Club | 3 | 3 | Black | -1 |
| Heart | 1 | 4 | Red | -1 |
Nous séparons maintenant un détail de programmation interne (nom d'énumération, valeur d'énumération) avec un paramètre d'affichage destiné aux utilisateurs:
SELECT Cards.Suit
FROM Cards
INNER JOIN Suits ON Cards.Suit = Suits.Suit
ORDER BY Suits.Rank,
Card.Rank*Suits.CardOrder