Gérer des couleurs en base de données

Il peut vite devenir difficile de gérer de façon uniforme les couleurs pour plusieurs applications accédant à une base de données :

– s’il s’agit d’une application web, les couleurs s’affichent sur 6 caractères alphanumériques de la base hexadécimale,
– s’il s’agit d’une application lourde, elle peut interpréter les couleurs comme un entier qui est la somme RVB, ou bien sous forme hexadécimale.

Voyons comment gérer cela simplement …

Voici une table qui fera tous les calculs automatiquement à partir des trois composantes RVB :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---------------------------------
-- Nicolas SOUQUET - 03/07/2009 -  
---------------------------------
CREATE TABLE TbCouleur
(
  IDCouleur INT NOT NULL IDENTITY CONSTRAINT PK_TbCouleur PRIMARY KEY,
  nomCouleur VARCHAR(10) NOT NULL CONSTRAINT UQ_TbCouleur_nomCouleur UNIQUE,
  composanteRouge TINYINT,
  composanteVert TINYINT,
  composanteBleu TINYINT,
  Decimale AS (composanteRouge + composanteVert * 256 + composanteBleu * 256 * 256) PERSISTED NOT NULL,
  Hexadecimale AS (CAST(composanteRouge + composanteVert * 256 + composanteBleu * 256 * 256 AS VARBINARY(3))) PERSISTED NOT NULL,
  HTML AS (dbo.Fn_RVB_To_HTML(composanteRouge, composanteVert, composanteBleu))  PERSISTED NOT NULL,
  CONSTRAINT UQ_TbCouleur_composanteRouge_composanteVert_composanteBleu UNIQUE (composanteRouge, composanteVert, composanteBleu)
)

L’utilisation de colonnes calculées (persistées, mais ce n’est pas obligatoire !) pour faire effectuer tous les calculs au moteur de base de données rend très simple toute saisie de nouvelles couleurs.

Pour calculer le codage HTML, nous utilisons la fonction suivante, dont le code est un peu barbare, mais efficace :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
---------------------------------
-- Nicolas SOUQUET - 03/07/2009 -  
---------------------------------
CREATE FUNCTION Fn_RVB_To_HTML
  (
    @rouge TINYINT,
    @vert TINYINT,
    @bleu TINYINT
  )
  RETURNS CHAR(6)
  WITH SCHEMABINDING
AS
BEGIN
  RETURN
  (
    CASE @rouge / 16
      WHEN 0 THEN '0'
      WHEN 1 THEN '1'
      WHEN 2 THEN '2'
      WHEN 3 THEN '3'
      WHEN 4 THEN '4'
      WHEN 5 THEN '5'
      WHEN 6 THEN '6'
      WHEN 7 THEN '7'
      WHEN 8 THEN '8'
      WHEN 9 THEN '9'
      WHEN 10 THEN 'A'
      WHEN 11 THEN 'B'
      WHEN 12 THEN 'C'
      WHEN 13 THEN 'D'
      WHEN 14 THEN 'E'
      WHEN 15 THEN 'F'
    END +
    CASE @rouge % 16
      WHEN 0 THEN '0'
      WHEN 1 THEN '1'
      WHEN 2 THEN '2'
      WHEN 3 THEN '3'
      WHEN 4 THEN '4'
      WHEN 5 THEN '5'
      WHEN 6 THEN '6'
      WHEN 7 THEN '7'
      WHEN 8 THEN '8'
      WHEN 9 THEN '9'
      WHEN 10 THEN 'A'
      WHEN 11 THEN 'B'
      WHEN 12 THEN 'C'
      WHEN 13 THEN 'D'
      WHEN 14 THEN 'E'
      WHEN 15 THEN 'F'
    END +
    CASE @vert / 16
      WHEN 0 THEN '0'
      WHEN 1 THEN '1'
      WHEN 2 THEN '2'
      WHEN 3 THEN '3'
      WHEN 4 THEN '4'
      WHEN 5 THEN '5'
      WHEN 6 THEN '6'
      WHEN 7 THEN '7'
      WHEN 8 THEN '8'
      WHEN 9 THEN '9'
      WHEN 10 THEN 'A'
      WHEN 11 THEN 'B'
      WHEN 12 THEN 'C'
      WHEN 13 THEN 'D'
      WHEN 14 THEN 'E'
      WHEN 15 THEN 'F'
    END +
    CASE @vert % 16
      WHEN 0 THEN '0'
      WHEN 1 THEN '1'
      WHEN 2 THEN '2'
      WHEN 3 THEN '3'
      WHEN 4 THEN '4'
      WHEN 5 THEN '5'
      WHEN 6 THEN '6'
      WHEN 7 THEN '7'
      WHEN 8 THEN '8'
      WHEN 9 THEN '9'
      WHEN 10 THEN 'A'
      WHEN 11 THEN 'B'
      WHEN 12 THEN 'C'
      WHEN 13 THEN 'D'
      WHEN 14 THEN 'E'
      WHEN 15 THEN 'F'
    END +
    CASE @bleu / 16
      WHEN 0 THEN '0'
      WHEN 1 THEN '1'
      WHEN 2 THEN '2'
      WHEN 3 THEN '3'
      WHEN 4 THEN '4'
      WHEN 5 THEN '5'
      WHEN 6 THEN '6'
      WHEN 7 THEN '7'
      WHEN 8 THEN '8'
      WHEN 9 THEN '9'
      WHEN 10 THEN 'A'
      WHEN 11 THEN 'B'
      WHEN 12 THEN 'C'
      WHEN 13 THEN 'D'
      WHEN 14 THEN 'E'
      WHEN 15 THEN 'F'
    END +
    CASE @bleu % 16
      WHEN 0 THEN '0'
      WHEN 1 THEN '1'
      WHEN 2 THEN '2'
      WHEN 3 THEN '3'
      WHEN 4 THEN '4'
      WHEN 5 THEN '5'
      WHEN 6 THEN '6'
      WHEN 7 THEN '7'
      WHEN 8 THEN '8'
      WHEN 9 THEN '9'
      WHEN 10 THEN 'A'
      WHEN 11 THEN 'B'
      WHEN 12 THEN 'C'
      WHEN 13 THEN 'D'
      WHEN 14 THEN 'E'
      WHEN 15 THEN 'F'
    END
  )
END

Ainsi l’ajout d’une nouvelle couleur dans la table se fait simplement :

1
2
3
4
5
6
7
8
9
10
11
12
13
---------------------------------
-- Nicolas SOUQUET - 03/07/2009 -  
---------------------------------
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Blanc', 255, 255, 255)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Noir', 0, 0, 0)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Gris', 190, 190, 190)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Rouge', 255, 0, 0)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Vert', 0, 255, 0)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Bleau', 0, 0, 255)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Jaune', 255, 255, 0)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Orange', 255, 165, 0)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Rose', 255, 192, 203)
INSERT INTO dbo.TbCouleur(nomCouleur, composanteRouge, composanteVert, composanteBleu) VALUES ('Violet', 238, 130, 238)

ou encore à l’aide de la procédure stockée suivante :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
---------------------------------
-- Nicolas SOUQUET - 03/07/2009 -  
---------------------------------
CREATE PROCEDURE Ps_Couleur_Ajouter
  @nomCouleur VARCHAR(10),
  @composanteRouge TINYINT,
  @composanteVert TINYINT,
  @composanteBleu TINYINT
AS
BEGIN
  INSERT INTO dbo.TbCouleur
  (
    nomCouleur,
    composanteRouge,
    composanteVert,
    composanteBleu
  )
  VALUES
  (
    @nomCouleur,
    @composanteRouge,
    @composanteVert,
    @composanteBleu
  )
END

Et pour ajouter les couleurs :

1
2
3
4
5
6
7
8
9
10
11
12
13
---------------------------------
-- Nicolas SOUQUET - 03/07/2009 -  
---------------------------------
EXEC dbo.Ps_Couleur_Ajouter 'Blanc', 255, 255, 255
EXEC dbo.Ps_Couleur_Ajouter 'Noir', 0, 0, 0
EXEC dbo.Ps_Couleur_Ajouter 'Gris', 190, 190, 190
EXEC dbo.Ps_Couleur_Ajouter 'Rouge', 255, 0, 0
EXEC dbo.Ps_Couleur_Ajouter 'Vert', 0, 255, 0
EXEC dbo.Ps_Couleur_Ajouter 'Bleau', 0, 0, 255
EXEC dbo.Ps_Couleur_Ajouter 'Jaune', 255, 255, 0
EXEC dbo.Ps_Couleur_Ajouter 'Orange', 255, 165, 0
EXEC dbo.Ps_Couleur_Ajouter 'Rose', 255, 192, 203
EXEC dbo.Ps_Couleur_Ajouter 'Violet', 238, 130, 238

Et le résultat est le suivant :

Les trois fonctions suivantes permettent d’obtenir la couleur souhaitée dans la représentation qui conviendra suivant l’application :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
-----------------------------------------------------
-- Nicolas SOUQUET - 03/07/2009 - Fn_Couleur_GetRVB -
-----------------------------------------------------
CREATE FUNCTION Fn_Couleur_GetRVB
  (@nomCouleur VARCHAR(10))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
  SELECT composanteRouge AS R,
      composanteVert AS V,
      composanteBleu AS B
  FROM dbo.TbCouleur
  WHERE nomCouleur = @nomCouleur
)
 
------------------------------------------------------
-- Nicolas SOUQUET - 03/07/2009 - Fn_Couleur_GetHTML -
------------------------------------------------------
CREATE FUNCTION Fn_Couleur_GetHTML
  (@nomCouleur VARCHAR(10))
  RETURNS CHAR(6)
  WITH SCHEMABINDING
AS
BEGIN
  RETURN
  (
    SELECT HTML
    FROM dbo.TbCouleur
    WHERE nomCouleur = @nomCouleur
  )
END
 
----------------------------------------------------------
-- Nicolas SOUQUET - 03/07/2009 - Fn_Couleur_GetDecimale -
----------------------------------------------------------
CREATE FUNCTION Fn_Couleur_GetDecimale
  (@nomCouleur VARCHAR(10))
  RETURNS INT
  WITH SCHEMABINDING
AS
BEGIN
  RETURN
  (
    SELECT Decimale
    FROM dbo.TbCouleur
    WHERE nomCouleur = @nomCouleur
  )
END
 
--------------------------------------------------------------
-- Nicolas SOUQUET - 03/07/2009 - Fn_Couleur_GetHexadecimale -
--------------------------------------------------------------
CREATE FUNCTION Fn_Couleur_GetHexadecimale
  (@nomCouleur VARCHAR(10))
  RETURNS VARBINARY(3)
  WITH SCHEMABINDING
AS
BEGIN
  RETURN
  (
    SELECT Hexadecimale
    FROM dbo.TbCouleur
    WHERE nomCouleur = @nomCouleur
  )
END

On peut ensuite envisager le code d’une procédure comme suit :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
---------------------------------
-- Nicolas SOUQUET - 03/07/2009 -  
---------------------------------
CREATE PROCEDURE maProcedure
  @...
  @application
AS
BEGIN
  SELECT CASE ETAT
        WHEN uneValeur THEN CASE @application
                    WHEN 'HTML' THEN dbo.Fn_Couleur_GetHTML('Rouge')
                    WHEN 'EXE' THEN dbo.Fn_Couleur_GetDecimale('Rouge')
                  END
        ELSE CASE @application
            WHEN 'HTML' THEN dbo.Fn_Couleur_GetHTML('Blanc')
            WHEN 'EXE' THEN dbo.Fn_Couleur_GetDecimale('Blanc')
          END
      END
  FROM dbo.TbEtat AS ETAT
END

Bien sûr il est préférable de stocker les divers états possibles dans une table et de gérer le CASE avec la valeur de clé de la table.
On peut également penser à récupérer une représentation d’une couleur à partir d’une autre …

ElSuket

Laisser un commentaire