Oracle
 sql >> Database >  >> RDS >> Oracle

Tipo di dati REAL in PLSQL

Il riferimento al linguaggio SQL dice "Il tipo di dati REAL è un numero a virgola mobile con una precisione binaria di 63, o 18 decimale", ed è mostrato come FLOAT(63). E FLOAT [(p)] è:

Se crei una tabella con una colonna REAL si comporta come 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

Ho usato un valore più piccolo in modo che possa essere visualizzato entro il limite SQL*Plus/SQL Developer di 49 cifre per numformat. Nota che i valori FLOAT(126) e NUMBER non sono esattamente gli stessi con quel valore.

PL/SQL è leggermente diverso. Nel pacchetto standard puoi vedere:

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

In un blocco PL/SQL il tuo REAL la variabile può assumere qualsiasi valore che non sia un NUMBER illimitato può e ha gli stessi effetti di scala/precisione; in questo caso conservando solo il (38- 40) cifre e arrotondando il resto alla minima di quelle prime 40 cifre. La "dimensione" complessiva del tuo valore, come numero di 72 cifre, viene conservata, ma perdi la precisione oltre ciò che può essere memorizzato nel formato interno di Oracle. Se hai gli stessi tipi di variabile dell'esempio di tabella e inserisci i tuoi valori originali in:

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

Nota questa volta che FLOAT e NUMBER senza restrizioni mostrano lo stesso valore, mentre i FLOAT con restrizioni hanno la precisione che ti aspetti.

Quindi mostra zeri dopo la 40a cifra e quella 40a cifra è 5 invece di 4 perché hai superato la precisione e il valore viene arrotondato alle cifre più significative. Il tipo di dati SQL REAL ha una precisione di 63 cifre binarie o 18 decimali; ma a meno che non sia specificato un PL/SQL REAL corrisponde a NUMBER.