FirebirdSQL logo
 Structure du langage SQLÉléments communs du langage 

Précision des opérations arithmétiques

Les fonctions MIN, MAX, SUM, AVG fonctionnent avec tous les types numériques exacts.SUM et AVG sont exacts si l’entrée traitée est de type numérique exact et que la somme mise à l’échelle correspond à 64 ou 128 bits : sinon une exception de débordement se produit.SUM et AVG ne sont jamais calculés en utilisant l’arithmétique à virgule flottante, sauf si le type de données de la colonne est un nombre approximatif.

Les fonctions MIN et MAX pour une colonne numérique exacte retournent un résultat numérique exact avec la même précision et la même échelle que la colonne.SUM et AVG pour un type numérique exact retourne un résultat de type NUMERIC ({18 | 38}, S) ou DECIMAL ({18 | 38}, S) où S est l’échelle de la colonne.La norme SQL définit l’échelle du résultat dans de tels cas, tandis que la précision de SUM ou AVG pour les colonnes à virgule fixe est définie par l’implémentation : nous la définissons comme 18 ou 38 (si la précision de l’argument est 18 ou 38).

Si les deux opérandes OP1 et OP2 sont des nombres exacts d’échelle S1 et S2 respectivement, alors OP1 + OP2 et OP1 - OP2 sont des nombres exacts de précision 18 ou 38 (si l’un des arguments est de précision 38) et d’échelle égale au plus grand de S1 et S2, alors que pour OP1 * OP2 et OP1 / OP2 sont des nombres exacts de précision 18 ou 38 (si les arguments sont de précision 18 ou 38) et d’échelle S1 + S2.Les échelles de ces opérations, sauf la division, sont définies par la norme SQL.La précision de toutes ces opérations et les échelles de division ne sont pas régies par la norme, mais sont définies par l’implémentation : Firebird définit la précision comme 18 ou 38 (si la précision de l’argument est 18 ou 38) et les échelles de division comme S1 + S2, les mêmes que celles définies par la norme pour la multiplication.

Lorsque des opérations arithmétiques sont effectuées sur des types numériques exacts, une erreur de dépassement sera signalée si la précision est perdue, plutôt que de renvoyer une valeur incorrecte. Par exemple, si la colonne DECIMAL (18,4) contient la valeur la plus négative de ce type, à savoir -922337203685477.5808, une tentative de division de cette colonne par -1 signalera une erreur de débordement car le résultat réel dépasse la plus grande valeur positive pouvant être représentée dans le type, à savoir 922337203685477.5807.

Si l’un des opérandes est un nombre exact et l’autre un nombre approximatif, le résultat de l’un des quatre opérateurs dyadiques sera de type DOUBLE PRECISION'.(La norme stipule que le résultat est un nombre approximatif avec au moins la même précision que l’opérande numérique approximatif : Firebird satisfait à cette exigence en utilisant toujours `DOUBLE PRECISION, puisque ce type est le type numérique approximatif maximum que Firebird fournit).

Types de données pour travailler avec la date et l’heure

Firebird utilise les types de données DATE, TIME et TIMESTAMP pour gérer les données contenant la date et l’heure.Dans le dialecte 3, les trois types de données ci-dessus sont présents, tandis que dans le dialecte 1, seul le type de données DATE est disponible pour les opérations de date et d’heure, qui n’est pas identique au type de données DATE du dialecte 3, mais est le type de données TIMESTAMP du dialecte 3.

Note

Dans le dialecte 1, le type DATE peut être déclaré comme TIMESTAMP.Cette déclaration est recommandée pour les nouvelles bases de données en dialecte 1.

Fractions de seconde

Dans les types TIMESTAMP et TIME, Firebird stocke les secondes avec des décimales.Si vous avez besoin d’une granularité inférieure, la précision peut être spécifiée explicitement en millièmes, centièmes ou dixièmes de seconde dans les bases de données en dialecte 3 et ODS 11 et plus.

Note
Quelques informations utiles sur l’exactitude des secondes

La partie temps des types TIME ou TIMESTAMP est un entier de 4 octets (WORD) contenant une valeur de temps avec des fractions de seconde, et stockée comme le nombre de dix millièmes de seconde écoulés depuis minuit.La précision réelle des valeurs obtenues à partir des fonctions et des variables de l’horodateur sera la suivante :

  • CURRENT_TIME — est précis à la seconde par défaut, la précision en millisecondes peut être spécifiée comme suit : CURRENT_TIME (0 | 1 | 2 | 3).

  • CURRENT_TIMESTAMP — est précise à la milliseconde près par défaut, une précision de la seconde à la milliseconde peut être spécifiée comme suitCOURANT_TIMESTAMP (0 | 1 | 2 | 3)

  • LOCALTIME — est précis à la seconde par défaut, la précision en millisecondes peut être spécifiée comme suitLOCALTIME (0 | 1 | 2 | 3)

  • LOCALTIMESTAMP — est précis à la milliseconde près par défaut, une précision de la seconde à la milliseconde peut être spécifiée comme suitLOCALTIMESTAMP (0 | 1 | 2 | 3)

  • Le littéral 'NOW' est précis en millisecondes ;

  • Les fonctions DATEADD et DATEDIFF supportent une précision au dixième de milliseconde.

  • La fonction EXTRACT renvoie des valeurs précises au dixième de milliseconde pour les arguments SECOND et MILLISECOND ;

Stockage des types de fuseaux horaires

Les types de données avec support de fuseau horaire sont stockés comme des valeurs UTC (offset 0) en utilisant la structure TIME ou TIMESTAMP.+ deux octets supplémentaires pour les informations relatives au fuseau horaire (soit un décalage en minutes, soit un identifiant de fuseau horaire nommé).

Le stockage en UTC permet à Firebird d’indexer et de comparer deux valeurs dans des fuseaux horaires différents.

Le stockage en UTC présente quelques inconvénients :

  • Lorsque vous utilisez des zones nommées et que les règles de fuseau horaire de cette zone changent, l’heure en UTC reste la même, mais l’heure locale dans la zone nommée peut changer.

  • Pour le type de données TIME WITH TIME ZONE, lors du calcul du décalage du fuseau horaire pour une zone nommée afin d’obtenir l’heure locale dans la zone, les règles en vigueur à partir du 1er janvier 2020 sont appliquées pour garantir une valeur stable.Cela peut conduire à des résultats inattendus ou déroutants.