ホームページ データベース 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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Oracle データベースのログはどのくらいの期間保存されますか? Oracle データベースのログはどのくらいの期間保存されますか? May 10, 2024 am 03:27 AM

Oracle データベース ログの保存期間は、次のようなログのタイプと構成によって異なります。 REDO ログ: 「LOG_ARCHIVE_DEST」パラメータで構成された最大サイズによって決定されます。アーカイブ REDO ログ: 「DB_RECOVERY_FILE_DEST_SIZE」パラメータで構成された最大サイズによって決まります。オンライン REDO ログ: アーカイブされず、データベースの再起動時に失われます。保持期間はインスタンスの実行時間と一致します。監査ログ: 「AUDIT_TRAIL」パラメータによって構成され、デフォルトで 30 日間保持されます。

Oracleで2つの日付の間の日数を計算する関数 Oracleで2つの日付の間の日数を計算する関数 May 08, 2024 pm 07:45 PM

2 つの日付の間の日数を計算する Oracle の関数は DATEDIFF() です。具体的な使用法は次のとおりです。 時間間隔の単位を指定します: 間隔 (日、月、年など) 2 つの日付値を指定します: date1 と date2DATEDIFF(interval, date1, date2) 日数の差を返します。

Oracle データベースの起動手順の順序は次のとおりです。 Oracle データベースの起動手順の順序は次のとおりです。 May 10, 2024 am 01:48 AM

Oracle データベースの起動シーケンスは次のとおりです。 1. 前提条件を確認します。 3. データベース インスタンスを起動します。 5. データベースに接続します。サービスを有効にします (必要な場合)。 8. 接続をテストします。

オラクルで間隔を使用する方法 オラクルで間隔を使用する方法 May 08, 2024 pm 07:54 PM

Oracle の INTERVAL データ型は、時間間隔を表すために使用されます。構文は INTERVAL <precision> <unit> です。INTERVAL の演算には、加算、減算、乗算、除算を使用できます。これは、時間データの保存などのシナリオに適しています。日付の差を計算します。

Oracle で特定の文字の出現数を確認する方法 Oracle で特定の文字の出現数を確認する方法 May 09, 2024 pm 09:33 PM

Oracle で文字の出現数を確認するには、次の手順を実行します。 文字列の全長を取得します。 文字が出現する部分文字列の長さを取得します。 部分文字列の長さを減算して、文字の出現数をカウントします。全長から。

Oracle データベース サーバーのハードウェア構成要件 Oracle データベース サーバーのハードウェア構成要件 May 10, 2024 am 04:00 AM

Oracle データベース サーバーのハードウェア構成要件: プロセッサ: マルチコア、少なくとも 2.5 GHz のメイン周波数 大規模なデータベースの場合は、32 コア以上が推奨されます。メモリ: 小規模データベースの場合は少なくとも 8 GB、中規模のデータベースの場合は 16 ~ 64 GB、大規模なデータベースまたは重いワークロードの場合は最大 512 GB 以上。ストレージ: SSD または NVMe ディスク、冗長性とパフォーマンスのための RAID アレイ。ネットワーク: 高速ネットワーク (10GbE 以上)、専用ネットワーク カード、低遅延ネットワーク。その他: 安定した電源、冗長コンポーネント、互換性のあるオペレーティング システムとソフトウェア、放熱と冷却システム。

Oracle にはどれくらいのメモリが必要ですか? Oracle にはどれくらいのメモリが必要ですか? May 10, 2024 am 04:12 AM

Oracle が必要とするメモリーの量は、データベースのサイズ、アクティビティー・レベル、および必要なパフォーマンス・レベル (データ・バッファー、索引バッファーの保管、SQL ステートメントの実行、およびデータ・ディクショナリー・キャッシュの管理) によって異なります。正確な量は、データベースのサイズ、アクティビティ レベル、および必要なパフォーマンス レベルによって影響されます。ベスト プラクティスには、適切な SGA サイズの設定、SGA コンポーネントのサイズ設定、AMM の使用、メモリ使用量の監視などが含まれます。

Oracleで文字列を置換する方法 Oracleで文字列を置換する方法 May 08, 2024 pm 07:24 PM

Oracle で文字列を置換する方法は、REPLACE 関数を使用することです。この関数の構文は、REPLACE(string, search_string, replace_string) です。使用手順: 1. 置換する部分文字列を特定します。 2. 部分文字列を置換する新しい文字列を決定します。 3. REPLACE 関数を使用して置換します。高度な使用法には、複数の置換、大文字と小文字の区別、特殊文字の置換などが含まれます。

See all articles