【问题标题】:What is the default Precision and Scale for a Number in Oracle?Oracle 中数字的默认精度和小数位数是多少?
【发布时间】:2010-10-10 05:48:33
【问题描述】:

在 Oracle 中创建 NUMBER 类型的列时,您可以选择不指定精度或小数位数。如果您不指定它们,这些默认值会做什么?

【问题讨论】:

    标签: database oracle number-formatting


    【解决方案1】:

    NUMBER(精度、比例)

    如果未指定精度,则列存储给定值。如果未指定比例,则比例为零。

    更多信息请访问:

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

    【讨论】:

    • 浮点数与离散的数字类型非常不同。所以,我认为它不会使用 float
    • 我知道它直接来自文档,但 IMO 的第二句话应该是:“如果指定了精度但未指定比例,则比例为零。”否则,两者都适用于number:“未指定比例”,表示“比例为零”(仅允许整数),以及“未指定精度”,表示“按给定”存储值(允许浮点数) . “给定”是 number 的实际情况,但不是因为没有重叠。幸运的是,他们澄清了 12c。
    • 我知道这个问题不是关于 SSIS,而是搜索把我带到了这里。如果我在 SSIS 中引用了一个没有精度或比例的 NUMBER 列,则它称它为浮点数 (DT_R8)。所以从我的角度来看,@qualidafial 是正确的
    • 文档中那个不真实的句子正是人们搜索这个的原因。那句话表明NUMBER 表示NUMBER(38, 0),这是不正确的,并且与后面显示的示例相矛盾。
    【解决方案2】:

    NUMBER类型可以在different styles中指定:

    结果 结果精度 规格 精度 刻度 检查 备注 ―――――――――――――――――――――――――――――――――――――――――――――――― ―――――――――――――――――――――――――――――― NUMBER NULL NULL NO 'maximum rangeprecision', 值存储'as given' NUMBER(P, S) P S YES 错误代码:ORA-01438 NUMBER(P) P 0 是 错误代码:ORA-01438 号码(*, S) 38 S 否

    其中精度是总位数,小数位数是 小数点左右(负数)位数。

    Oracle 将 ORA-01438 指定为

    值大于该列允许的指定精度

    如表中所述,此完整性检查仅在精度为 是明确指定的。否则,Oracle 会默默地舍入插入的或更新的 使用一些未指定的方法的值。

    【讨论】:

    • 我投票赞成这个答案。如果您仅将列定义为 NUMBER,您将拥有最大精度和最大比例。如果将列定义为 NUMBER(5),则精度为 5,小数位数为 0。
    • *NUMBER 中的 precision 是什么意思?如果我定义 a NUMBER(*,0) 并尝试插入 123456789123456789123456789123456789123456789(即 45 位)怎么办?将存储什么?为什么?数学是什么?
    • @Nawaz, * 只是表示 Oracle 使用其默认值,即 38。这意味着 NUMBER(*, 0) 等同于 NUMBER(38, 0)。如果您尝试在NUMBER(38,0) 列中插入一个包含 45 个十进制数字的数字,则会出现错误。
    • @maxschlepzig:但是如果我在NUMBER(*,0) 中插入一个 45 位数字,那么它会成功没有任何警告,尽管有一些舍入。所以,这意味着NUMBER(38,0)NUMBER(*,0) 相同。 INT/INTEGER/SMALLINT 的行为似乎与 NUMBER(*,0) 相同。
    • @Nawaz,然后 Oracle Number semantics 更加复杂 - 使用星号可以获得 38 位精度(“精度为 38”),但似乎只有在两个参数时才能进行完整性检查明确指定:'当您指定数字字段时,最好指定精度和小数位数。这提供了额外的输入完整性检查。 - Oracle 没有指定在 38 位之后如何舍入 - 可能也取决于平台。下周我会更新表格。
    【解决方案3】:

    我相信默认精度是 38,默认比例为零。 但是,此列实例的实际大小是动态的。存储该值将占用尽可能多的空间,或最多 21 个字节。

    【讨论】:

    • 这个答案不正确。你可以很容易地举一个反例:create table ex(n number); insert into ex(n) values(1.5); select * from ex;你回来1.5。使用scale=0,您将返回1。这也被记录在案,例如在 11.2 Oracle 文档中,只有 NUMBER(无精度和无比例)导致“最大范围和精度”。
    【解决方案4】:

    Oracle 以下列方式存储数字:1 byte 代表幂,1 byte 代表第一个有效数字(即分隔符之前的数字),其余数字代表其他数字。

    这里的digits Oracle 表示centesimal digits(即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
    

    如我们所见,这里的最大数字是7.(7) * 10^124,他有19 百位精度表示,或38 十进制数字。

    【讨论】:

      【解决方案5】:

      其实你可以自己测试一下。

      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) ) ;

      选择 column_name、data_type、可为空、data_length、data_precision、data_scale 来自 user_tab_columns 其中 table_name ='CUSTOMERS';

      【讨论】:

      • 不幸的是,这并没有显示 NUMBER 的默认精度和小数位数,它只返回 NULL CUSTOMER_ID DATA_TYPE:NUMBER NULLABLE:N DATA_LENGTH:22 DATA_PRECISION:(null) DATA_SCALE:(null)
      • 但是,如果您通过插入非常大的数字进行测试,所有内容都会显示出来:CREATE TABLE TEST_NUMBER (N1 NUMBER);插入 TEST_NUMBER(N1)值(98765432109876543210987654321098765432109876543210.01234567890123456789);从 TEST_NUMBER 中选择 N1;产量:98765432109876543210987654321098765432110000000000
      【解决方案6】:

      我扩展了光谱的答案,这样人们就不必自己尝试了。

      这是在 Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production 上完成的。

      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'; 
      

      产生的结果

      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    
      

      【讨论】:

        猜你喜欢
        • 2022-01-14
        • 2020-09-09
        • 2013-07-17
        • 1970-01-01
        • 1970-01-01
        • 2012-05-26
        • 1970-01-01
        • 1970-01-01
        • 2015-03-18
        相关资源
        最近更新 更多