데이터 베이스 MySQL 튜토리얼 ORACLE数值类型详解--NUMBER、BINARY

ORACLE数值类型详解--NUMBER、BINARY

Jun 07, 2016 pm 03:44 PM
oracle 수치 유형 상해

在9i之前,ORACLE为我们提供了Number数类型,在10g中,ORACLE又引入了BINARY_FLOAT和BINARY_DOUBLE数据类型。除此之外,还有integer,smallint等数据类型,但这些类型的底层实现依然是NUMBER、BINARY_FLOAT、BINARY_DOUBLE。 因此,我们可以认为ORACLE总共为

        在9i之前,ORACLE为我们提供了Number数值类型,在10g中,ORACLE又引入了BINARY_FLOAT和BINARY_DOUBLE数据类型。除此之外,还有integer,smallint等数据类型,但这些类型的底层实现依然是NUMBER、BINARY_FLOAT、BINARY_DOUBLE。因此,我们可以认为ORACLE总共为我们提供了三种存储数值的数据类型:NUMBER、BINARY_FLOAT、BINARY_DOUBLE。通过这三种数值类型,可以存储正值,负值,0,无穷大和NAN(not a number)。

NUMBER

        number类型在oracle中会占用0~22个字节的存储空间,是一种变长数据类型,采用oracle内部算法,是一种软数据类型,因此具有较好的数据精确度,通用性和可移植性较强,但是其运算效率相对一浮点类型(硬件运算)偏低。在0~22个字节的存储空间中,一个字节用于存储数据长度,21个字节用于存储数据(其中一个字节存储与符号和指数相关的内容,20个字节用于存储数据)。

        number存储数据的范围如下:

        正数:1 x 10-130 to 9.99...9 x 10125 ,数据精度为38个有效数字

      负数:-1 x 10-130 to 9.99...99 x 10125 ,数据精度为38个有效数字

      零:0

      无穷大:仅仅只可以从oracle 5中导入

number有效数字

        可以通过如下格式来指定:COLUMN_NAME number(precision ,scale),其中precision指number可以存储的最大数字长度(不包括左右两边的0),scale指在小数点右边的最大数字长度(包括左侧0)。如果我们指定了p和s,可以按照如下算法来判读数据是否有效:如果s>=0,首先我们从小数点从左向右数s个数字,如果在此之右,仍然有数据,则将其截断,然后我们在当前位置再向左侧数p个数字,如果在此之左仍有非零数字,则数字不合法,否则数据合法;如果s

        如果我们没有指定phes如:column_name number,则数字按照输入格式存储;如果我们指定了p,但是没有指定s,则s默认为0,如column_name number(p);如果我们指定了s但是没有指定p,则p默认为38,如column_name number(*,s)。

        p的取值范围为1-38,在官方文档中有这样一段话:

       Oracle guarantees the portability of numbers with precision of up to 20 base-100 digits, which is equivalent to 39 or 40 decimal digits depending on the position of the decimal point.由于在内部采用20个字节存储数据,每个字节存储2位数字,因此最多可以存放40个数字,及文档中谈及的40,但是如果小数点左侧的数字数量为奇数,则左侧补一位0,那么这是有效数字就最大为39。在语法上,oracle规定precision为38,可能是为了稳妥或者其他的原因。

        s的取值范围为-84~127,这也是与number的内部存储格式有关,不做过多的讨论。

[sql

SQL> create table t6(c1 number,c2 number(*,1),c3 number(9),c4 number(9,2),c5 number(9,1),c6 number(6),c7 number(7,-2));  

  

表已创建。  

  

SQL> insert into t6 values(7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89);  

insert into t6 values(7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89)  

                                                                             *  

第 1 行出现错误:  

ORA-01438: 值大于为此列指定的允许精度  

  

  

SQL> insert into t6 values(7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,0,7456123.89);  

  

已创建 1 行。  

  

SQL> commit;  

[sql

SQL> select * from t6;  

  

      C1           C2       C3       C4       C5       C6       C7  

------------ ------------ ------------ ------------ ------------ ------------ ------------  

  7456123.89    7456123.9      7456124   7456123.89    7456123.9        0      7456100  

number存储结构

        number数据类型的存储结构,可以通过dump函数来展现,在探究number存储结构之前,让我们先来看一下dump函数的使用方法。

        DUMP函数的输出格式类似:

类型 ,符号/指数位 [数字1,数字2,数字3,……,数字20]

        其中各参数的含义如下:

·类型指字段数据类型,Number型,Type=2(类型代码可以从Oracle的文档上查到);

·长度指存储的字节数;

·符号/指数位用于代表数字的正负及指数值;

·数据存储。

 

        oracle采用21个字节存储number,第一个字节为头信息,随后20个字节存储有效数字。

         头信息        数据域1      数据域2   .............. 数据域n (n

         XXXXXXXXXXXXXXXX XXXXXXXX ............XXXXXXXX

         |  |                   |-一个字节存储2个十进制数字,可以存储0-99,因为0在c语言中作为特殊字符,因此用1-100来存储0-99,即在原值上加1。在数据域不存储正负符号,为了

         |  |                   |-排序的方便,对于负数,我们用101-2来存储0-99(为什么不用100-1,请高手指教),在负数的最后会添加一个值为102的字节,这是为了避免排序错误

         |  |-数据指数范围标识位,当正数时,该数值与64做差(x-64),其结果为指数,当负数时,63与该数值做差(63-x),其结果为指数。在oracle中0X80,代表0,因此对于

         |  |-正数,其指数范围为-63~0(小数) 1~63(非小数);对于负数,指数范围为63~1(非小数),0~-64(小数)

         |-符号信息位,1代表正数,0代表负数

          查询是,对于存储在数据域的数据,oracle会将每个字节转换为十进制,然后拼接各个字节。如果指数域的值为正数n,那么会将小数点定位在第n个字节的后面,如果为0,则小数点在第一个字节的前面,如果为负数,则小数点在第一个字节向前推进n个字节。

 

        下面,我们通过实例来看一下上面的说法正不正确:

[sql] 

desc tab1  

名称 空值 类型              

-- -- -------------   

C1    NUMBER          

C2    VARCHAR2(300)   

 

 

ORACLE数值类型详解--NUMBER、BINARY

 

 

如果负数的精度很 大,102比较位可能会被舍弃,因此此时102已经起不到任何作用了。

       

[sql

SQL> insert into tab1 values(-111111111111111111111111111111111111111111111111111111111111);  

  

已创建 1 行。  

  

SQL> select dump(c1) from tab1;  

  

DUMP(C1)  

--------------------------------------------------  

Typ=2 Len=2: 193,2  

Typ=2 Len=3: 62,100,102  

Typ=2 Len=1: 128  

Typ=2 Len=6: 197,2,24,46,68,90  

Typ=2 Len=7: 58,100,78,56,34,12,102  

Typ=2 Len=12: 58,100,78,56,34,12,3,25,47,69,91,102  

Typ=2 Len=11: 197,2,24,46,68,90,99,77,55,33,11  

Typ=2 Len=21: 33,90,90,90,90,90,90,90,90,90,90,90,  

90,90,90,90,90,90,90,90,90  

 

number变种

        除number类型外,oracle还为我们提供了一些number的变种数据类型,这些类型其内部实现仍然是number,我们可以将其理解为number的特定别名。

NUMERIC(p,s):完全映射至NUMBER(p,s)。如果p未指定,则默认为38.

DECIMAL(p,s)或DEC(p,s):完全映射至NUMBER(p,s)。如果p为指定,则默认为38

INTEGER或INT:完全映射至NUMBER(38)类型。

SMALLINT:完全映射至NUMBER(38)类型。

 

FLOAT(b):映射至NUMBER类型。

 

DOUBLE PRECISION:映射至NUMBER类型。

 

REAL:映射至NUMBER类型。

在这里需要特别注意的是float类型,参加官方文档:

        The FLOAT data type is a subtype of NUMBER. It can be specified with or without precision, which has the same definition it has for NUMBER and can rangefrom 1 to 

126. Scale cannot be specified, but is interpreted from the data. Each FLOAT value requires from 1 to 22 bytes.

        To convert from binary to decimal precision, multiply n by 0.30103. To convert from decimal to binary precision, multiply the decimal precision by 3.32193. The maximum of 126 digits of binary precision is roughly equivalent to 38 digits of decimal precision.

        由此可知,float中的有效数指的是二进制格式的有效数,转换为10进制为b*0.30103. 如果结果不是整数,则采用上侧整数作为底层number存储的precision。如:

[sql

SQL> desc tab1  

 名称                                      是否为空? 类型  

 ----------------------------------------- -------- ----------------------------  

 C1                                                 FLOAT(2)  

 C2                                                 FLOAT(4)  

 C3                                                 FLOAT(6)  

 C4                                                 FLOAT(7)  

 C5                                                 FLOAT(9)  

 C6                                                 FLOAT(11)  

 C7                                                 FLOAT(13)  

  

SQL> insert into tab1 values(1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321);  

  

已创建 1 行。  

  

SQL> select * from tab1;  

  

        C1         C2         C3         C4         C5         C6         C7  

---------- ---------- ---------- ---------- ---------- ---------- ----------  

1000000000 1200000000 1200000000 1230000000 1230000000 1235000000 1235000000  

PLS_INTEGER和BINARY_INTEGER

        PLS_INTEGER和BINARY_INTEGER是plsql数据类型,无法在表中直接使用。在11g的官方文档中,官方指出PLS_INTEGER和BINARY_INTEGER两者是相同的,是有符号的整数类型,其取值范围为-2^31 ~  2^31,共占用32个比特位。其内部存储格式,尚无资料表明,通过dump函数查看其为number类型,这可能是不正确的(补充:后来dump varchar2和nvarchar2数据类型时,其typ均为1,由此可见dump可能对相似的数据类型使用相同的typ),因为官方文档明确指出了PLS_INTEGER BINARY_INTEGER通number的一下区别:

       1.存储空间要比number小

       2.计算效率要比number高,因此可以直接硬件运算,而number是软运算。

        如果赋值范围超出了PLS_INTEGER和BINARY_INTEGER的范围,将会发生溢出异常;

[sql

DECLARE  

  p1 PLS_INTEGER := 2147483647;  

  p2 PLS_INTEGER := 1;  

  n NUMBER;  

BEGIN  

  n := p1 + p2;  

END;  

/  

Result:  

DECLARE  

*  

ERROR at line 1:  

ORA-01426: numeric overflow  

ORA-06512: at line 6  

        在11g中,oracle引入了simple_integer,该类型是PLS_INTEGER的子类型,取值范围相同,但是该类型不会进行空值和溢出检测(必须人为保证非空和不会发生溢出),因此与PLS_INTEGER相比,具有更高的性能。如果可以确定某个值为非空并且不会发生溢出操作,可以使用simple_integer来存储。由于不会进行溢出检测,simple_integer的运算结果可能会发生正负值的转换,例如:

[sql

DECLARE  

  n SIMPLE_INTEGER := 2147483645;  

BEGIN  

  FOR j IN 1..4 LOOP  

    n := n + 1;  

    DBMS_OUTPUT.PUT_LINE(TO_CHAR(n, 'S9999999999'));  

  END LOOP;  

  FOR j IN 1..4 LOOP  

   n := n - 1;  

   DBMS_OUTPUT.PUT_LINE(TO_CHAR(n, 'S9999999999'));  

  END LOOP;  

 12  END;  

 13  /  

+2147483646  

+2147483647  

-2147483648  

-2147483647  

-2147483648  

+2147483647  

+2147483646  

+2147483645  

  

PL/SQL 过程已成功完成。  

         如果将simple_integer转换为pls_integer, 会转换为pls_integer not null。

BINARY_FLOAT和BINARY_DOUBLE

        oracle根据IEEE754实现单精度和双精度浮点型,要了解IEEE754,请参照http://blog.csdn.net/yidian815/article/details/12912661 

        由于存储结构上的不同,BINARY_FLOAT和BINARY_DOUBLE较number,可以存储更大范围的数据,但是其精度并不如number。如果存储金融数据,建议使用number,而如果进行科学运算,建议使用BINARY_FLOAT和BINARY_DOUBLE,因为浮点型数据使用的是硬件计算,其计算效率是非常高的。

 

        我们可以通过如下方式来判断某个浮点型是否为无穷或者非数值。

        

        expr is [not] NAN

        expr is [not] INFINITE

        ORACLE可以对NAN排序,排序规则是,NAN最大,NAN与NAN比较时,其值相等。infinity和infinity相比,其值相等。

[sql

SQL> create table tab1(id number,c1 binary_float,c2 binary_double);  

  

表已创建。  

  

SQL> insert into tab1 values(1,1,1);  

  

已创建 1 行。  

  

SQL> insert into tab1 values(2,nan,nan);  

insert into tab1 values(2,nan,nan)  

                              *  

第 1 行出现错误:  

ORA-00984: 列在此处不允许  

  

  

SQL> insert into tab1 values(2,binary_float_nan,binary_double_nan);  

  

已创建 1 行。  

  

SQL> insert into tab1 values(3,binary_float_infinity,binary_double_infinity);  

  

已创建 1 行。  

  

SQL> insert into tab1 values(4,-binary_float_infinity,-binary_double_infinity);  

  

已创建 1 行。  

  

SQL> commit;  

  

提交完成。  

  

SQL> select * from tab1;  

  

    ID         C1     C2  

------ ---------- ----------  

     1   1.0E+000   1.0E+000  

     2        Nan    Nan  

     3        Inf    Inf  

     4       -Inf   -Inf  

  

SQL> select * from tab1 order by c1;  

  

    ID         C1     C2  

------ ---------- ----------  

     4       -Inf   -Inf  

     1   1.0E+000   1.0E+000  

     3        Inf    Inf  

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 is infinite;  

  

    ID         C1     C2  

------ ---------- ----------  

     3        Inf    Inf  

     4       -Inf   -Inf  

  

SQL> select * from tab1 where c1 is nan;  

  

    ID         C1     C2  

------ ---------- ----------  

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 = binary_float_infinity;  

  

    ID         C1     C2  

------ ---------- ----------  

     3        Inf    Inf  

  

SQL> select * from tab1 where c1 != binary_float_infinity;  

  

    ID         C1     C2  

------ ---------- ----------  

     1   1.0E+000   1.0E+000  

     2        Nan    Nan  

     4       -Inf   -Inf  

  

SQL> select * from tab1 where c1 = (select c1 from tab1 where id =2);  

  

    ID         C1     C2  

------ ---------- ----------  

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 = nan;  

select * from tab1 where c1 = nan  

                              *  

第 1 行出现错误:  

ORA-00904: "NAN": 标识符无效  

  

  

SQL> select * from tab1 where c1 = binary_float_nan;  

  

    ID         C1     C2  

------ ---------- ----------  

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 = (select c1 from tab1 where id =3);  

  

    ID         C1     C2  

------ ---------- ----------  

     3        Inf    Inf  

  

SQL>   

优先级:在数据转换时,优先转换为高级别的数据类型

date type > binary_double > binary_float > number > char

 

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. 크로스 플레이가 있습니까?
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Oracle의 테이블 스페이스 크기를 확인하는 방법 Oracle의 테이블 스페이스 크기를 확인하는 방법 Apr 11, 2025 pm 08:15 PM

Oracle 테이블 스페이스 크기를 쿼리하려면 다음 단계를 따르십시오. 쿼리를 실행하여 테이블 스페이스 이름을 결정하십시오. 쿼리를 실행하여 테이블 스페이스 크기를 쿼리하십시오. sum (bytes)을 total_size, sum (bytes_free)으로 sum (bytes_free), sum (bytes) - sum (bytes_free)으로 dba_data_fices where tablespace_.

오라클에서 시간을 얻는 방법 오라클에서 시간을 얻는 방법 Apr 11, 2025 pm 08:09 PM

Oracle에는 시간을 얻는 방법이 있습니다. current_timestamp : 현재 시스템 시간을 반환합니다. Systimestamp : current_timestamp보다 나노 초보다 더 정확합니다. sysdate : 시간 부분을 제외하고 현재 시스템 날짜를 반환합니다. to_char (sysdate, 'yyy-mm-dd hh24 : mi : ss') : 현재 시스템 날짜와 시간을 특정 형식으로 변환합니다. 추출 : 1 년, 월 또는 시간과 같은 시간 값에서 특정 부분을 추출합니다.

Oracle View를 암호화하는 방법 Oracle View를 암호화하는 방법 Apr 11, 2025 pm 08:30 PM

Oracle View 암호화를 사용하면보기에서 데이터를 암호화 할 수 있으므로 민감한 정보의 보안을 향상시킬 수 있습니다. 단계에는 다음이 포함됩니다. 1) 마스터 암호화 키 생성 (MEK); 2) 암호화 된 뷰 생성, 암호화 할보기 및 MEK를 지정하는 것; 3) 사용자가 암호화 된보기에 액세스하도록 승인합니다. 암호화 된 뷰 작동 방식 : 사용자가 암호화 된보기를 쿼리 할 때 Oracle은 MEK를 사용하여 데이터를 해독하여 공인 사용자 만 읽기 쉬운 데이터에 액세스 할 수 있도록합니다.

Oracle의 인스턴스 이름을 보는 방법 Oracle의 인스턴스 이름을 보는 방법 Apr 11, 2025 pm 08:18 PM

Oracle에서 인스턴스 이름을 보는 세 가지 방법이 있습니다. 명령 줄에 명령. "show instance_name"을 사용하십시오. sql*plus의 명령. 운영 체제의 작업 관리자, Oracle Enterprise Manager 또는 운영 체제를 통해 환경 변수 (Linux의 Oracle_Sid)를 확인하십시오.

Oracle 설치를 제거하는 방법에 실패했습니다 Oracle 설치를 제거하는 방법에 실패했습니다 Apr 11, 2025 pm 08:24 PM

Oracle 설치 실패에 대한 방법 제거 : Oracle Service를 닫고 Oracle Program 파일 및 레지스트리 키 삭제, Oracle 환경 변수를 제거하고 컴퓨터를 다시 시작하십시오. 제거되지 않으면 Oracle 범용 제거 도구를 사용하여 수동으로 제거 할 수 있습니다.

Oracle 사용자를 설정하는 방법 Oracle 사용자를 설정하는 방법 Apr 11, 2025 pm 08:21 PM

Oracle에서 사용자를 만들려면 다음 단계를 따르십시오. 사용자 명령문을 사용하여 새 사용자를 만듭니다. 보조금 명세서를 사용하여 필요한 권한을 부여하십시오. 선택 사항 : 리소스 문을 사용하여 할당량을 설정하십시오. 기본 역할 및 임시 테이블 스페이스와 같은 다른 옵션을 구성하십시오.

유효하지 않은 수의 Oracle을 확인하는 방법 유효하지 않은 수의 Oracle을 확인하는 방법 Apr 11, 2025 pm 08:27 PM

Oracle 유효하지 않은 숫자 오류는 데이터 유형 불일치, 숫자 오버플로, 데이터 변환 오류 또는 데이터 손상으로 인해 발생할 수 있습니다. 문제 해결 단계에는 데이터 유형 확인, 디지털 오버 플로우 감지, 데이터 변환 확인, 데이터 손상 확인 및 NLS_NUMERIC_CHARACTERS 매개 변수 구성 및 데이터 확인 로깅 활성화와 같은 다른 가능한 솔루션 탐색이 포함됩니다.

Oracle Dynamic SQL을 만드는 방법 Oracle Dynamic SQL을 만드는 방법 Apr 12, 2025 am 06:06 AM

SQL 문은 Oracle의 동적 SQL을 사용하여 런타임 입력을 기반으로 작성 및 실행할 수 있습니다. 단계에는 다음이 포함됩니다 : 동적으로 생성 된 SQL 문을 저장할 빈 문자열 변수 준비. 즉시 실행 또는 준비 명령문을 사용하여 동적 SQL 문을 컴파일하고 실행하십시오. 바인드 변수를 사용하여 사용자 입력 또는 기타 동적 값을 동적 SQL로 전달하십시오. 동적 SQL 문을 실행하려면 즉시 실행 또는 실행을 사용하십시오.

See all articles