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

 

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 number BINARY_FLOAT
BINARY_DOUBLE_NAN :not a number BINARY_DOUBLE
BINARY_FLOAT_INFINITY :BINARY_FLOAT 無限大值
BINARY_DOUBLE_INFINITY :BINARY_DOUBLE 無限大值
IS NAN :NAN 判斷
IS NOT NAN :NAN 判斷
IS INFINITE 無窮大判斷
IS NOT INFINITE 無窮大判斷
 
一個對比 NUMBER BINARY_DOUBLE BINARY_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值
-------------------------
如下圖:
《oracle pl/sql programming》 第9章 数值_第1张图片
三角函數(略)
 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,calendar,IBM,Integer,float,Numbers)