《oracle pl/sql programming》 第9章 数值

原创 2007年10月12日 17:51:00

 

1.數值類型介紹
oracle提供三種基本的數值類型,
NUMBER
最通用也是最基本的,不依賴與特定的硬件平臺,超大長度,適用于貨幣,不會丟失精度,整數小數通用。
 
PLS_INTEGER 和 BINARY_INTEGER
這兩個類型是依賴與當前硬件平臺的整型,因此可能不具備平臺通用性,但是相對于NUMBER,其效能高出許多。
10g以后,兩者是等價的。
 
BINARY_FLOAT 和 BINARY_DOUBLE
這是oracle提供的符合IEEE-754標準的浮點類型,前者是單精度的,后者是雙精度的。不建議用這種類型來存儲貨幣數據。因為這類浮點數在運算時會丟失,或者說損失精度。
 
使用舉例:
DECLARE
 var1 NUMBER; --定義了一個最大寬度的NUMBER變量,可用于整型和小數類型,
 var2 NUMBER(9);--定義了一個寬度為9的整型
 var3 NUMBER(9,3); --定義了一個NUMBER變量,精度為9,小數位數2
BEGIN
 var1 := 1;
 var1 := 1234.56
 var2 := 123456789;
 var3 := 123456.789;
 ...
 DBMS_OUTPUT.PUT_LINE(0.95f); --BINARY_FLOAT
 DBMS_OUTPUT.PUT_LINE(0.95d); --BINARY_DOUBLE
 DBMS_OUTPUT.PUT_LINE(0.95); --NUMBER
 ...
oracle為兼容其他的一些標準和數據庫,在以上三種數值類型的基礎上,創建了一些子類型,如下:
---------------------------------------------------------
子類型                 兼容性        與基本類型的對照
DEC (precision, scale) ANSI     NUMBER (precision, scale)
DECIMAL (precision, scale) IBM       NUMBER (precision, scale)
DOUBLE PRECISION       ANSI     NUMBER, with 126 binary digits of precision
FLOAT                  ANSI, IBM     NUMBER, but with a precision of 126 binary digits
FLOAT (binary_precision)   ANSI, IBM     NUMBER, but with a binary_precision of up to 126 (the default)
INT               ANSI     NUMBER
INTEGER           ANSI, IBM     NUMBER
NATURAL           N/A      PLS_INTEGER,a but allows only nonnegative values (0 and higher)
NATURALN          N/A      Same as NATURAL, but with the additional restriction of never being NULL
NUMERIC (precision, scale) ANSI     NUMBER (precision, scale)
POSITIVE          N/A      PLS_INTEGER,a but allows only positive values (1 and higher)
POSITIVEN              N/A      Same as POSITIVE, but with the additional restriction of never being NULL
REAL              ANSI     NUMBER, with 63 binary digits of precision.
SIGNTYPE          N/A      PLS_INTEGER,a limited to the values -1, 0, and 1
SMALLINT          ANSI, IBM     NUMBER (38)
-------------------------------------------------------
 
幾個特殊常量值
BINARY_FLOAT_NAN:not a numberBINARY_FLOAT
BINARY_DOUBLE_NAN:not a numberBINARY_DOUBLE
BINARY_FLOAT_INFINITY:BINARY_FLOAT無限大值
BINARY_DOUBLE_INFINITY:BINARY_DOUBLE無限大值
IS NAN:NAN判斷
IS NOT NAN:NAN判斷
IS INFINITE無窮大判斷
IS NOT INFINITE無窮大判斷
 
一個對比NUMBERBINARY_DOUBLEBINARY_FLOAT的效能的程序
    DECLARE
       bd BINARY_DOUBLE;
       bd_area BINARY_DOUBLE;
       bd_sine BINARY_DOUBLE;
       nm NUMBER;
       nm_area NUMBER;
       nm_sine NUMBER;
       pi_bd BINARY_DOUBLE := 3.1415926536d;
       pi_nm NUMBER := 3.1415926536;
       bd_begin TIMESTAMP(9);
       bd_end TIMESTAMP(9);
       bd_wall_time INTERVAL DAY TO SECOND(9);
       nm_begin TIMESTAMP(9);
       nm_end TIMESTAMP(9);
       nm_wall_time INTERVAL DAY TO SECOND(9);
    BEGIN
       --Compute area 5,000,000 times using binary doubles
       bd_begin := SYSTIMESTAMP;
       bd := 1d;
       LOOP
          bd_area := bd * bd * pi_bd;
          bd := bd + 1d;
          EXIT WHEN bd > 5000000;
       END LOOP;
       bd_end := SYSTIMESTAMP;
 
       --Compute area 5,000,000 times using NUMBERs
       nm_begin := SYSTIMESTAMP;
       nm := 1;
       LOOP
          nm_area := nm * nm * 2 * pi_nm;
          nm := nm + 1;
          EXIT WHEN nm > 5000000;
       END LOOP;
       nm_end := SYSTIMESTAMP;
 
       --Compute and display elapsed, wall-clock time
       bd_wall_time := bd_end - bd_begin;
       nm_wall_time := nm_end - nm_begin;
       DBMS_OUTPUT.PUT_LINE('BINARY_DOUBLE area = ' || bd_wall_time);
       DBMS_OUTPUT.PUT_LINE('NUMBER area = ' || nm_wall_time);
 
       --Compute sine 5,000,000 times using binary doubles
       bd_begin := SYSTIMESTAMP;
       bd := 1d;
       LOOP
          bd_sine := sin(bd);
          bd := bd + 1d;
          EXIT WHEN bd > 5000000;
       END LOOP;
       bd_end := SYSTIMESTAMP;
 
       --Compute sine 5,000,000 times using NUMBERs
       nm_begin := SYSTIMESTAMP;
       nm := 1;
       LOOP
          nm_sine := sin(nm);
          nm := nm + 1;
          EXIT WHEN nm > 5000000;
       END LOOP;
       nm_end := SYSTIMESTAMP;
 
       --Compute and display elapsed, wall-clock time for sine
       bd_wall_time := bd_end - bd_begin;
       nm_wall_time := nm_end - nm_begin;
       DBMS_OUTPUT.PUT_LINE('BINARY_DOUBLE sine = ' || bd_wall_time);
       DBMS_OUTPUT.PUT_LINE('NUMBER sine = ' || nm_wall_time);
    END;
輸出結果(因不同機器而異):
    BINARY_DOUBLE area = +00 00:00:02.792692000
    NUMBER area = +00 00:00:08.942327000
    BINARY_DOUBLE sine = +00 00:00:04.149930000
    NUMBER sine = +00 00:07:37.596783000
 
2.類型轉換
TO_NUMBER(string [,format [,nls_params]])
format轉換舉例
    DECLARE
       a NUMBER;
       b NUMBER;
       c NUMBER;
       d NUMBER;
       e BINARY_FLOAT;
       f BINARY_DOUBLE;
       g BINARY_DOUBLE;
 
       n1 VARCHAR2(20) := '-123456.78';
       n2 VARCHAR2(20) := '+123456.78';
    BEGIN
       a := TO_NUMBER('123.45');
       b := TO_NUMBER(n1);
       c := TO_NUMBER(n2);
       d := TO_NUMBER('1.25E2');
       e := TO_BINARY_FLOAT('123.45');
       f := TO_BINARY_DOUBLE('inf');/* inf表示正無窮大,-inf表示負無窮大 */
       g := TO_BINARY_DOUBLE('NAN');/* NAN表示not a number */
    END;
 
format轉換舉例
   a := TO_NUMBER('$123,456.78','L999G999D99');
 
關于format的說明請參考附錄B
 
NLS參數
    SQL> SELECT * FROM nls_session_parameters
 
    PARAMETER                 VALUE
    ------------------------- ---------------
    NLS_LANGUAGE              AMERICAN
    NLS_TERRITORY             AMERICA
    NLS_CURRENCY              $
    NLS_ISO_CURRENCY          AMERICA
    NLS_NUMERIC_CHARACTERS    .,
    NLS_CALENDAR              GREGORIAN
    NLS_DATE_FORMAT           DD-MON-RR
 
      a := TO_NUMBER('F123.456,78','L999G999D99',
                     'NLS_NUMERIC_CHARACTERS='',.'''
                     || ' NLS_CURRENCY=''F'''
                     || ' NLS_ISO_CURRENCY=FRANCE');
 
 
 
TO_CHAR(number [,format [,nls_params]])
format轉換
    DECLARE
       b VARCHAR2(30);
    BEGIN
       b := TO_CHAR(123456789.01);
       DBMS_OUTPUT.PUT_LINE(b);
    END;
輸出
    123456789.01
format轉換
    DECLARE
       b VARCHAR2(30);
    BEGIN
       b := TO_CHAR(123456789.01,'L999G999G999D99');
       DBMS_OUTPUT.PUT_LINE(b);
    END;
輸出:
    $123,456,789.01
關于format的說明請參考附錄B。
 
3.數值函數
Rounding 和 Trancation函數
函數     說明
-------------------------
CEIL    返回與當前數最接近的大于等于當前數的整數
FLOOR   返回與當前數最接近的小于等于當前數的整數
ROUND   以四舍五入的方法返回指定小數位數的當前數的round值
TRUNC   以舍去多余位的方法返回指定小數位數的當前數的round值
-------------------------
如下圖:
三角函數(略)
 ACOS (-1) = pi(圓周率)
 
數值函數快速參考
ABS
取絕對值
 
BITAND
按位與
 
數學函數
COS(n)
COSH(n)
ACOS(n)
ASIN(n)
ATAN(n)
ATAN2(n, m)
EXP(n)
SQRT(n)
TAN(n)
TANH(n)
SIN(n)
SINH(n)
 
BIN_TO_NUM(b1, b2,...bn)
二進制toNUMBER 如:BIN_TO_NUM(1,1,0,0) = 12
 
GREATEST(n1, n2,...n3)
返回最大者
 
LEAST(n1, n2,...n3)
返回最小者
 
NANVL(n, m)
if n is NAN then m else n;
 
 

oracle 11g PL/SQL Programming学习十七

---------------------------------------------------------------------------- -----------------PL/SQ...
  • edcvf3
  • edcvf3
  • 2013年06月21日 00:32
  • 3180

oracle 11g PL/SQL Programming学习十六

---------------------------------------------------------------------------- -----------------PL/SQ...
  • edcvf3
  • edcvf3
  • 2013年06月19日 00:39
  • 2515

oracle pl/sql宝典(第2版)

《oracle pl/sql宝典(第2版)》共分4 篇。     第1篇 介绍oracle 和pl/sql 基础知识;     第2篇 介绍数据表的创建和操作、表中数据的操作、数据的基本查询、查询...
  • u012213585
  • u012213585
  • 2013年12月05日 16:25
  • 653

PL/SQL 数据类型和变量 -- 数值

-- Start PL/SQL 支持 SQL 的数值数据类型,除此之外,它还定义了自己的子类型。有关 SQL 数值数据类型,参见此处。 DECLARE -- 声明变量并赋值 TES...
  • shangboerds
  • shangboerds
  • 2014年12月21日 23:45
  • 1557

浅谈ORACLE中ORA-06502:PL/SQL:数字或值错误:字符到数值的转换错误

原因之一:查看在输出的字符串拼接中是否使用了(+),ORACLE中的字符拼接是(||),当然大家还可以使用CONCAT(),但是要注意使用CONCAT()函数最多只能拼接两个参数的字符 EXAM...
  • start1032314909
  • start1032314909
  • 2014年05月13日 11:29
  • 703

Oracle PL/SQL编程详解之三: PL/SQL流程控制语句

[推荐]Oracle PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆)  本篇主要内容如下: 3.1  条件语句 3.2  CASE 表达式 ...
  • zhglance
  • zhglance
  • 2017年04月03日 21:00
  • 571

免安装Oracle运行pl/sql developer

 Sql客户端中,虽然最便捷的是万能而且轻量无比的Sql Workbench,唯一的遗憾是只支持JDK5,不过这个小小的遗憾只要配置配置就能避免。     Otherwise,Oracle来说,用起来...
  • devoteinjava
  • devoteinjava
  • 2007年04月18日 10:27
  • 2197

oracle 11g PL/SQL Programming学习一

第一章 概览        PL/SQL历史背景(history and background)        PL/SQL是随着oracle在80年代末发展起来的.最初,其功能还很有限,但是在9...
  • edcvf3
  • edcvf3
  • 2012年08月09日 17:22
  • 2408

源码-PL/SQL从入门到精通-第二章-PL/SQL基本概念-Part 1

随书附带的源码没有序号,部分有bug,调试过程中一并更正。 --代码2.1 使用书序结构计算员工薪资 DECLARE v_sal1 NUMBER; v_sal2 NUMBER; ...
  • hpdlzu80100
  • hpdlzu80100
  • 2016年07月13日 12:21
  • 2901

ORA-00913: 值过多 ORA-06550: 第 2 行, 第 4 列: PL/SQL: SQL Statement ignored

ORA-00913: 值过多 ORA-06550: 第 2 行, 第 4 列:  PL/SQL: SQL Statement ignored 两张表字段不一致,或者插入时字段与数据不一致...
  • lcz0615
  • lcz0615
  • 2015年04月25日 18:14
  • 2187
收藏助手
不良信息举报
您举报文章:《oracle pl/sql programming》 第9章 数值
举报原因:
原因补充:

(最多只允许输入30个字)