sql >> Databasteknik >  >> RDS >> Oracle

RIKTIG datatyp i PLSQL

SQL-språkreferensen säger "Den REAL datatypen är ett flyttalstal med en binär precision på 63, eller 18 decimaler", och den visas som FLOAT(63). Och FLOAT [(p)] är:

Om du skapar en tabell med en REAL-kolumn fungerar den som en 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

Jag har använt ett mindre värde så att det kan visas inom SQL*Plus/SQL-utvecklargränsen på 49 siffror för numformat. Lägg märke till att FLOAT(126)- och NUMBER-värdena inte är riktigt lika med det värdet.

PL/SQL är något annorlunda. I standardpaketet kan du se:

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

I en PL/SQL blockera din REAL variabel kan ta vilket värde som helst än ett obegränsat NUMBER kan och har samma skala/precisionseffekter; i det här fallet bevaras bara den mest betydande (38- 40) siffror, och avrunda resten till den minsta av de första 40 siffrorna. Den övergripande "storleken" på ditt värde, som ett 72-siffrigt tal, bevaras, men du tappar precisionen utöver vad som kan lagras i Oracles interna format. Om du har samma variabeltyper som tabellexemplet och lägger dina ursprungliga värden i:

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

Lägg märke till den här gången att den obegränsade FLOAT och NUMBER visar samma värde, medan de begränsade FLOAT har den precision du förväntar dig.

Så det visar nollor efter den 40:e siffran och den 40:e siffran är 5 istället för 4 eftersom du har överskridit precisionen och värdet avrundas till de mest signifikanta siffrorna. SQL REAL-datatypen har en precision på 63 binära eller 18 decimalsiffror; men om inte specificerats matchar ett PL/SQL REAL NUMMER.




  1. Databasversionskontroll för MySQL

  2. PHP och MySQL:Antal returnerade rader

  3. Postgres hur man implementerar beräknad kolumn med klausul

  4. Multi-Cloud Full Databas Cluster Failover-alternativ för PostgreSQL