Oracle
 sql >> Base de données >  >> RDS >> Oracle

Type de données REAL dans PLSQL

La référence du langage SQL dit "Le type de données REAL est un nombre à virgule flottante avec une précision binaire de 63, ou 18 décimal", et il est affiché comme FLOAT(63). Et FLOAT [(p)] vaut :

Si vous créez une table avec une colonne REAL, elle se comporte comme un FLOAT(63) :

create table t42 (a real, b float(126), c float(63), d number);
insert into t42 (a, b, c, d)
values (123456789123456789123456789123456789123456789123456,
  123456789123456789123456789123456789123456789123456,
  123456789123456789123456789123456789123456789123456,
  123456789123456789123456789123456789123456789123456);

select a, b, c, d from t42;

                                                               A
----------------------------------------------------------------
                                                               B
----------------------------------------------------------------
                                                               C
----------------------------------------------------------------
                                                               D
----------------------------------------------------------------
             123456789123456789100000000000000000000000000000000 
             123456789123456789123456789123456789120000000000000 
             123456789123456789100000000000000000000000000000000 
             123456789123456789123456789123456789123000000000000

J'ai utilisé une valeur plus petite afin qu'elle puisse être affichée dans la limite SQL*Plus/SQL Developer de 49 chiffres pour numformat. Notez que les valeurs FLOAT(126) et NUMBER ne sont pas tout à fait les mêmes avec cette valeur.

PL/SQL est légèrement différent. Dans le package standard, vous pouvez voir :

  type NUMBER is NUMBER_BASE;
  subtype FLOAT is NUMBER; -- NUMBER(126)
  subtype REAL is FLOAT; -- FLOAT(63)

Dans un bloc PL/SQL votre REAL la variable peut prendre n'importe quelle valeur qu'un NUMBER sans restriction peut et a les mêmes effets d'échelle/précision ; dans ce cas, ne conserver que les (38- 40) chiffres et arrondir le reste au plus petit de ces 40 premiers chiffres. La "taille" globale de votre valeur, sous la forme d'un nombre à 72 chiffres, est conservée, mais vous perdez la précision au-delà de ce qui peut être stocké dans le format interne d'Oracle. Si vous avez les mêmes types de variables que dans l'exemple de tableau et mettez vos valeurs d'origine dans :

DECLARE
  A REAL := 123456789123456789123456789123456789123456789123456789123456789123456789;
  B FLOAT(126) := 123456789123456789123456789123456789123456789123456789123456789123456789;
  c FLOAT(63) := 123456789123456789123456789123456789123456789123456789123456789123456789;
  D NUMBER := 123456789123456789123456789123456789123456789123456789123456789123456789;
BEGIN
  DBMS_OUTPUT.PUT_LINE('A Value is : ' || A);
  DBMS_OUTPUT.PUT_LINE('B Value is : ' || B);
  DBMS_OUTPUT.PUT_LINE('C Value is : ' || C);
  DBMS_OUTPUT.PUT_LINE('D Value is : ' || D);
END;
/

A Value is : 123456789123456789123456789123456789123500000000000000000000000000000000
B Value is : 123456789123456789123456789123456789120000000000000000000000000000000000
C Value is : 123456789123456789100000000000000000000000000000000000000000000000000000
D Value is : 123456789123456789123456789123456789123500000000000000000000000000000000

Notez cette fois que les FLOAT et NUMBER non restreints affichent la même valeur, tandis que les FLOAT restreints ont la précision que vous attendez.

Il affiche donc des zéros après le 40e chiffre et ce 40e chiffre est 5 au lieu de 4 car vous avez dépassé la précision et la valeur est arrondie aux chiffres les plus significatifs. Le type de données SQL REAL a une précision de 63 chiffres binaires ou 18 chiffres décimaux; mais sauf indication contraire, un REAL PL/SQL correspond à NUMBER.