Was ist die Standardgenauigkeit und -skalierung für eine Zahl in Oracle?

73

Beim Erstellen einer Spalte vom Typ NUMBER in Oracle haben Sie die Möglichkeit, keine Genauigkeit oder Skalierung anzugeben. Was machen diese Standardeinstellungen, wenn Sie sie nicht angeben?

Matt
quelle

Antworten:

44

NUMMER (Präzision, Skalierung)

Wenn keine Genauigkeit angegeben wird, werden in der Spalte die angegebenen Werte gespeichert. Wenn keine Skala angegeben ist, ist die Skala Null.

Viel mehr Infos unter:

http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1832

Angelo Marcotullio
quelle
2
Float unterscheidet sich stark vom diskreten Zahlentyp. Also, ich würde denken, es wird nicht float
paolov
5
Ich weiß, dass es direkt aus den Dokumenten stammt, aber IMO sollte der zweite Satz lauten: " Wenn die Genauigkeit angegeben ist , die Skalierung jedoch nicht , ist die Skalierung Null." Andernfalls gelten beide für number: "Es wird keine Skalierung angegeben", was bedeutet, dass "die Skalierung Null ist" (nur Ganzzahlen sind zulässig) und "Eine Genauigkeit ist nicht angegeben", was bedeutet, dass Werte "wie angegeben" gespeichert werden (Gleitkommazahlen zulässig). "Wie gegeben" ist das, was tatsächlich zutrifft number, aber nicht aus Mangel an Überlappung. Zum Glück haben sie für 12c geklärt.
Eric Eskildsen
1
Ich kenne die Frage nicht nach SSIS, aber eine Suche hat mich hierher gebracht. Wenn ich NUMBERin SSIS auf eine Spalte ohne Genauigkeit oder Skalierung verweise, wird sie als float (DT_R8) bezeichnet. Also aus meiner Sicht ist @qualidafial richtig
Nick.McDermaid
2
Dieser unwahre Satz in der Dokumentation ist genau der Grund, warum Leute danach suchen. Dieser Satz besagt , dass NUMBERMittel NUMBER(38, 0), die nicht wahr ist, und widerspricht dem Beispiel später gezeigt.
ddekany
25

Der NUMBERTyp kann in verschiedenen Stilen angegeben werden :

                Resultierende resultierende Präzision
Spezifikation Präzisionsskalenprüfung Kommentar
- ――――――――――――――――――――――――――――――――
NUMBER NULL NULL NO          'maximale Reichweite und Präzision' ,
                                                 Werte werden 'wie angegeben' gespeichert
NUMMER (P, S) PS JA Fehlercode: ORA-01438
NUMMER (P) P 0 JA Fehlercode: ORA-01438
NUMMER (*, S) 38 S NR

Dabei ist die Genauigkeit die Gesamtzahl der Stellen und die Skalierung die Anzahl der Stellen rechts oder links (negative Skala) des Dezimalpunkts.

Oracle gibt ORA-01438 als an

Wert größer als die angegebene Genauigkeit, die für diese Spalte zulässig ist

Wie in der Tabelle angegeben, ist diese Integritätsprüfung nur aktiv, wenn die Genauigkeit explizit angegeben ist. Andernfalls rundet Oracle den eingefügten oder aktualisierten Wert stillschweigend mit einer nicht angegebenen Methode.

maxschlepzig
quelle
Ich stimme für diese Antwort. Wenn Sie die Spalte nur als NUMBER definieren, haben Sie maximale Genauigkeit und maximale Skalierung. Wenn Sie die Spalte als NUMBER (5) definieren, ist die Genauigkeit 5, die Skala ist 0.
toree
Was *bedeutet Präzision in NUMBER? Was ist, wenn ich definiere a NUMBER(*,0)und versuche einzufügen 123456789123456789123456789123456789123456789(dh 45 Ziffern)? Was wird gespeichert? und warum? Was ist die Mathematik?
Nawaz
@Nawaz *bedeutet nur, dass Oracle seine Standardeinstellung verwendet, dh 38. Das bedeutet, dass dies NUMBER(*, 0)äquivalent zu ist NUMBER(38, 0). Wenn Sie versuchen, eine Zahl mit 45 Dezimalstellen in eine NUMBER(38,0)Spalte einzufügen , wird eine Fehlermeldung angezeigt.
Maxschlepzig
2
@maxschlepzig: Wenn ich aber eine 45-stellige Zahl in a einfüge NUMBER(*,0), gelingt dies ohne Vorwarnung, allerdings mit einigen Rundungen. Das bedeutet NUMBER(38,0)und NUMBER(*,0)ist nicht dasselbe. INT/INTEGER/SMALLINTscheint sich so zu verhalten, als NUMBER(*,0)ob.
Nawaz
2
@Nawaz, dann ist die Oracle Number-Semantik noch komplizierter - mit dem Sternchen erhalten Sie 38 Stellen Genauigkeit ('die Genauigkeit ist 38'), aber es scheint, dass Sie nur dann eine Integritätsprüfung erhalten, wenn beide Parameter explizit angegeben sind: 'Wenn Sie angeben Bei numerischen Feldern empfiehlt es sich, die Genauigkeit und Skalierung anzugeben. Dies bietet eine zusätzliche Integritätsprüfung bei der Eingabe. ' - Oracle gibt nicht an, wie es nach den 38 Ziffern rundet - wahrscheinlich auch plattformabhängig. Ich werde die Tabelle nächste Woche aktualisieren.
Maxschlepzig
15

Ich glaube, die Standardgenauigkeit ist 38, die Standardskala ist Null. Die tatsächliche Größe einer Instanz dieser Spalte ist jedoch dynamisch. Es wird so viel Speicherplatz benötigt, wie zum Speichern des Werts erforderlich ist, oder maximal 21 Byte.

Baretta
quelle
8
Diese Antwort ist nicht korrekt. Sie können leicht ein Gegenbeispiel geben: create table ex(n number); insert into ex(n) values(1.5); select * from ex;Sie kommen zurück 1.5. Mit scale=0würden Sie zurückkommen 1. Dies wird auch dokumentiert, z. B. mit 11.2 Oracle-Dokumenten, die nur NUMBER(ohne Genauigkeit und ohne Skalierung) zu "maximaler Reichweite und Genauigkeit" führen.
Maxschlepzig
10

Oraclespeichert Zahlen auf folgende Weise: 1 bytefür die Potenz 1 bytefür die erste signifikante Ziffer (dh eine vor dem Trennzeichen), den Rest für die anderen Ziffern.

Mit digitshier Oraclebedeutet centesimal digits(dh base 100)

SQL> INSERT INTO t_numtest VALUES (LPAD('9', 125, '9'))
  2  /

1 row inserted

SQL> INSERT INTO t_numtest VALUES (LPAD('7', 125, '7'))
  2  /

1 row inserted

SQL> INSERT INTO t_numtest VALUES (LPAD('9', 126, '9'))
  2  /

INSERT INTO t_numtest VALUES (LPAD('9', 126, '9'))

ORA-01426: numeric overflow

SQL> SELECT DUMP(num) FROM t_numtest;

DUMP(NUM)
--------------------------------------------------------------------------------
Typ=2 Len=2: 255,11
Typ=2 Len=21: 255,8,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,79

Wie wir sehen können, ist die maximale Anzahl hier 7.(7) * 10^124und er hat 19Centesimalstellen für die Genauigkeit oder 38Dezimalstellen.

Quassnoi
quelle
5

Eigentlich können Sie es immer selbst testen.

CREATE TABLE CUSTOMERS ( CUSTOMER_ID NUMBER NOT NULL, JOIN_DATE DATE NOT NULL, CUSTOMER_STATUS VARCHAR2(8) NOT NULL, CUSTOMER_NAME VARCHAR2(20) NOT NULL, CREDITRATING VARCHAR2(10) ) ;

select column_name, data_type, nullable, data_length, data_precision, data_scale from user_tab_columns where table_name ='CUSTOMERS';

Spektren
quelle
1
Dies zeigt leider nicht die Standardgenauigkeit und -skalierung von NUMBER, sondern gibt nur NULL zurück. CUSTOMER_ID DATA_TYPE: NUMBER NULLABLE: N DATA_LENGTH: 22 DATA_PRECISION: (null) DATA_SCALE: (null)
Ed Randall
2
Wenn Sie jedoch testen, indem Sie sehr große Zahlen einfügen, wird alles angezeigt: CREATE TABLE TEST_NUMBER (N1 NUMBER); INSERT INTO TEST_NUMBER (N1) VALUES (98765432109876543210987654321098765432109876543210.01234567890123456789); SELECT N1 FROM TEST_NUMBER; Ausbeuten: 98765432109876543210987654321098765432110000000000
Ed Randall
2

Ich erweitere die Antwort von spectra, damit die Leute es nicht selbst ausprobieren müssen.

Dies wurde in Oracle Database 11g Express Edition Version 11.2.0.2.0 - Produktion durchgeführt.

CREATE TABLE CUSTOMERS
(
  CUSTOMER_ID NUMBER NOT NULL,
  FOO FLOAT NOT NULL,
  JOIN_DATE DATE NOT NULL,
  CUSTOMER_STATUS VARCHAR2(8) NOT NULL,
  CUSTOMER_NAME VARCHAR2(20) NOT NULL,
  CREDITRATING VARCHAR2(10)
);

select column_name, data_type, nullable, data_length, data_precision, data_scale
from user_tab_columns where table_name ='CUSTOMERS'; 

Welche ergibt

COLUMN_NAME      DATA_TYPE  NULLABLE DATA_LENGTH DATA_PRECISION DATA_SCALE
CUSTOMER_ID      NUMBER     N        22        
FOO              FLOAT      N        22          126    
JOIN_DATE        DATE       N        7        
CUSTOMER_STATUS  VARCHAR2   N        8        
CUSTOMER_NAME    VARCHAR2   N        20        
CREDITRATING     VARCHAR2   Y        10    
bugybunny
quelle