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值
-------------------------
如下圖:
三角函數(略)
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;