Cette section fournit des exemples d'améliorations de la qualité des calculs mathématiques en MySQL 5, en comparaison avec les anciennes versions.
Exemple 1 Les nombres sont utilisés avec leur valeur exacte dès que possible.
Avant MySQL 5.0.3, les nombres étaient traités comme des nombres décimaux, avec des résultats inexacts :
mysql> SELECT .1 + .2 = .3;
+--------------+
| .1 + .2 = .3 |
+--------------+
|            0 |
+--------------+
Depuis MySQL 5.0.3, les nombres sont utilisés tels que spécifiés, tant que possible :
mysql> SELECT .1 + .2 = .3;
+--------------+
| .1 + .2 = .3 |
+--------------+
|            1 |
+--------------+
Cependant, pour les valeurs décimales, les erreurs de précision existent toujours :
mysql> SELECT .1E0 + .2E0 = .3E0;
+--------------------+
| .1E0 + .2E0 = .3E0 |
+--------------------+
|                  0 |
+--------------------+
Un autre moyen de voir la différence entre les valeurs exactes et les approximations est d'ajouter un grand nombre de fois des petites valeurs. Considérez la procédure stockée suivante quie ajoute .0001 mille fois à une variable.
CREATE PROCEDURE p ()
BEGIN
  DECLARE i INT DEFAULT 0;
  DECLARE d DECIMAL(10,4) DEFAULT 0;
  DECLARE f FLOAT DEFAULT 0;
  WHILE i < 10000 DO
    SET d = d + .0001;
    SET f = f + .0001E0;
    SET i = i + 1;
  END WHILE;
  SELECT d, f;
END;
      La somme de d et f vaut
      logiquement 1, mais ce n'est vrai que pour le calcul décimal. Les
      calculs décimaux introduisent une erreur :
    
+--------+------------------+ | d | f | +--------+------------------+ | 1.0000 | 0.99999999999991 | +--------+------------------+
      Exemple 2 La multiplication est
      faite avec l'échelle imposée par le standard SQL. C'est à dire
      que pour deux nombres X1 et
      X2 qui ont pour échelle respective
      S1 et S2, le
      résultat du produit est l'échelle
      S1 +
      S2
Avant MySQL 5.0.3, ceci arrivait :
mysql> SELECT .01 * .01;
+-----------+
| .01 * .01 |
+-----------+
|      0.00 |
+-----------+
La valeur affichée est incorrecte. La valeur a été calculée correctement dans cette situation, mais n'est pas affichée avec l'échelle nécessaire. Pour afficher la valeur correcte, il faut utiliser ceci :
mysql> SELECT .01 * .01 + .0000;
+-------------------+
| .01 * .01 + .0000 |
+-------------------+
|            0.0001 |
+-------------------+
Depuis MySQL 5.0.3, l'échelle finale est correcte :
mysql> SELECT .01 * .01;
+-----------+
| .01 * .01 |
+-----------+
| 0.0001    |
+-----------+
Exemple 3 L'arrondissement est bien maîtrisé.
      Avant MySQL 5.0.3, l'arrondissement (par exemple, avec
      ROUND()) était lié à l'implémentation de la
      bibliothèque C sous-jacente. Cela conduisait à des incohérences
      entre les plates-formes. Par exemple, cela arrivait si vous
      essayiez de faire le même calcul sur Windows et sur Linux, ou sur
      différentes architectures telles que des x86 ou des PowerPC.
    
Depuis MySQL 5.0.3, l'arrondissement se fait comme ceci :
      l'arrondit des colonnes DECIMAL des valeurs
      exactes utilisent la règle du ``arrondi à la valeur
      supérieure''. Les valeurs ayant une partie décimale supérieure
      ou égale à .5 sont arrondies au prochain entier, comme ceci :
    
mysql> SELECT ROUND(2.5), ROUND(-2.5);
+------------+-------------+
| ROUND(2.5) | ROUND(-2.5) |
+------------+-------------+
| 3          | -3          |
+------------+-------------+
L'arrondit des valeurs décimales utilise toujours la bibliothèque C, qui applique la règle de l'arrondit à l'entier le plus proche :
mysql> SELECT ROUND(2.5E0), ROUND(-2.5E0);
+--------------+---------------+
| ROUND(2.5E0) | ROUND(-2.5E0) |
+--------------+---------------+
|            2 |            -2 |
+--------------+---------------+
Exemple 4 Pour les insertions dans les tables, une valeur trop grande qui engendre un dépassement de capacité cause maintenant une erreur, et non plus la troncation de la valeur. Pour cela, il faut être en mode strict :
Avant MySQL 5.0.2, la troncation se faisait à la valeur valide la plus proche :
mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 128;Query OK, 1 row affected, 1 warning (0.01 sec) mysql>SELECT i FROM t;+------+ | i | +------+ | 127 | +------+ 1 row in set (0.00 sec)
Depuis MySQL 5.0.2, le dépassement de capacité intervient dès que le mode strict est actif :
mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.01 sec) mysql>SET sql_mode='STRICT_ALL_TABLES';Query OK, 0 rows affected (0.10 sec) mysql>INSERT INTO t SET i = 128;ERROR 1264 (22003): Out of range value adjusted for column 'i' at row 1 mysql>SELECT i FROM t;Empty set (0.00 sec)
      Exemple 5 Lors des insertions
      dans les tables, les divisions par zéro causent des erreur, et
      non plus des insertions de valeur NULL. Il faut
      utiliser le mot script et l'option
      ERROR_FOR_DIVISION_BY_ZERO.
    
      Avant MySQL 5.0.2, la division par zéro conduisait à un
      NULL :
    
mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO t SET i = 1 / 0;Query OK, 1 row affected (0.06 sec) mysql>SELECT i FROM t;+------+ | i | +------+ | NULL | +------+ 1 row in set (0.01 sec)
Depuis MySQL 5.0.2, la division par zéro est une erreur si le bon mode SQL est actif :
mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.00 sec) mysql>SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 1 / 0;ERROR 1365 (22012): Division by 0 mysql>SELECT i FROM t;Empty set (0.01 sec)
Exemple 6 En MySQL 4, les valeurs litérales exactes et approximatives sont converties en nombres décimaux en double précision :
mysql>CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;mysql>DESCRIBE t;+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | a | double(3,1) | | | 0.0 | | | b | double | | | 0 | | +-------+-------------+------+-----+---------+-------+
      En MySQL 5, la nombre décimaux approximative sont toujours
      convertis en nombres décimaux en précision double, mais les
      valeurs exactes sont gérées comme des nombres décimaux en
      précision simple DECIMAL :
    
mysql>CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;mysql>DESCRIBE t;+-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | a | decimal(3,1) | NO | | 0.0 | | | b | double | NO | | 0 | | +-------+--------------+------+-----+---------+-------+
Exemple 7 Si un argument d'une fonction d'agrégation est une valeur exacte, le résultat sera aussi exact, avec une échelle au moins égale à cet argument. Le résultat ne sera pas un nombre décimal de précision double.
Considérez les commandes suivantes :
mysql>CREATE TABLE t (i INT, d DECIMAL, f FLOAT);mysql>INSERT INTO t VALUES(1,1,1);mysql>CREATE TABLE y SELECT AVG(i), AVG(d), AVG(f) FROM t;
Le résultat avant MySQL 5.0.3 :
mysql> DESCRIBE y;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| AVG(i) | double(17,4) | YES  |     | NULL    |       |
| AVG(d) | double(17,4) | YES  |     | NULL    |       |
| AVG(f) | double       | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
Le résultat est un nombre décimal en précision double, quel que soit le type des arguments.
Le résultat depuis MySQL 5.0.3 :
mysql> DESCRIBE y;
+--------+---------------+------+-----+---------+-------+
| Field  | Type          | Null | Key | Default | Extra |
+--------+---------------+------+-----+---------+-------+
| AVG(i) | decimal(64,0) | YES  |     | NULL    |       |
| AVG(d) | decimal(64,0) | YES  |     | NULL    |       |
| AVG(f) | double        | YES  |     | NULL    |       |
+--------+---------------+------+-----+---------+-------+
Le résultat est un nombre décimal en précision double pour les arguments de type nombre décimal. Le résultat est une valeur exacte pour les arguments exacts.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

