oracle 数字与汉字转换(一)

2014-11-24 14:25:35 · 作者: · 浏览: 0
这是一个oracle函数,可以将阿拉伯数字与汉字进行相互转化,如1234567890.0123可以转化为“十二亿三千四百五十六万七千八百九十点零一二三”,同样也可以将汉字转化为对应的数字。

该函数支持千兆下的浮点数字,但不支持指数形式。
Sql代码 收藏代码

/* Formatted on 2009/12/22 17:03 (Formatter Plus v4.8.8) */
CREATE OR REPLACE PACKAGE czutil
AS
--将数字转化为汉字,支持千兆级数字的操作
FUNCTION num2chi (numvalue IN NUMBER)
RETURN VARCHAR2;

--将汉字转化为数字,支持千兆级数字的操作
FUNCTION chi2num (chivalue IN VARCHAR2)
RETURN NUMBER;
END;

CREATE OR REPLACE PACKAGE BODY czutil
AS
FUNCTION num2chi (numvalue IN NUMBER)
RETURN VARCHAR2
IS
--汉字映射数字的映射表
TYPE MAP IS TABLE OF VARCHAR2 (10)
INDEX BY BINARY_INTEGER;

ling_jiu_map MAP;
shibaiqian_map MAP;
wanyizhao_map MAP;
--临时变量
i INT := 0; --'临时变量
j INT := 0; --临时变量
k INT := 0; --临时变量
x INT := 0; --临时变量
y INT := 0; --临时变量
str VARCHAR2 (100) := ''; --临时变量
tmp VARCHAR2 (100) := ''; --临时变量
integer_part VARCHAR2 (100) := ''; --数字形式整数部分
float_part VARCHAR2 (100) := ''; --数字形式小数部分
returnvalue VARCHAR2 (100) := ''; --返回值
BEGIN
--初始化数组
ling_jiu_map (0) := '零';
ling_jiu_map (1) := '一';
ling_jiu_map (2) := '二';
ling_jiu_map (3) := '三';
ling_jiu_map (4) := '四';
ling_jiu_map (5) := '五';
ling_jiu_map (6) := '六';
ling_jiu_map (7) := '七';
ling_jiu_map (8) := '八';
ling_jiu_map (9) := '九';
shibaiqian_map (0) := '';
shibaiqian_map (1) := '十';
shibaiqian_map (2) := '百';
shibaiqian_map (3) := '千';
wanyizhao_map (0) := '';
wanyizhao_map (1) := '万';
wanyizhao_map (2) := '亿';
wanyizhao_map (3) := '兆';
--将数字拆分为整数与浮点数两个数字数组
i := INSTR (numvalue, '.', 1);

IF i = 0
THEN
integer_part := SUBSTR (numvalue, 1);
ELSE
integer_part := FLOOR (numvalue);
float_part := SUBSTR (numvalue, i + 1);
END IF;

--计算整数部分
i := LENGTH (integer_part);
j := CEIL (i / 4);
k := 0;

--将整数部分每四个分为一个组
FOR k IN 0 .. j - 1
LOOP
IF k = 0
THEN
str := SUBSTR (integer_part, 1, i - 4 * j + 4);
ELSE
str := SUBSTR (integer_part, i - 4 * j + 4 * k + 1, 4);
END IF;

x := LENGTH (str);
y := 0;
tmp := '';

--将每个组中数据转化为汉字
FOR y IN 0 .. x - 1
LOOP
tmp :=
tmp
|| ling_jiu_map (SUBSTR (str, y + 1, 1))
|| shibaiqian_map (x - y - 1);
END LOOP;

--零处理
tmp := RTRIM (tmp, '零'); --去掉兆亿万前面个位上的零
tmp := REGEXP_REPLACE (tmp, '(零[千百十])', '零'); --千百十位上的零
tmp := REGEXP_REPLACE (tmp, '(零{2,})', '零'); --将千百十位上的零结合
returnvalue := returnvalue || tmp || wanyizhao_map (j - k - 1);
END LOOP;

--零处理
--去掉兆亿万上的零
returnvalue := REGEXP_REPLACE (returnvalue, '(零[兆亿万])', '零');
--将兆亿万位上的零结合
returnvalue := REGEXP_REPLACE (returnvalue, '(零{2,})', '零');
--简称十位上的一
returnvalue := REGEXP_REPLACE (returnvalue, '^一十', '十');
returnvalue := REGEXP_REPLACE (returnvalue, '零一十', '零十');

--放进返回结果
IF returnvalue IS NULL
THEN
returnvalue := '零';
END IF;

IF float_part IS NOT NULL
THEN
--计算小数部分
k := 0;
tmp := '';

FOR k IN 1 .. LENGTH (float_part)
LOOP
tmp := tmp || ling_jiu_map (SUBSTR (float_part, k, 1));
END LOOP;

returnvalue := returnvalue || '点' || tmp;
END IF;

RETURN returnvalue;
END;

FUNCTION chi2num (chivalue IN VARCHAR2)
RETURN NUMBER
IS
--汉字映射数字的映射表
TYPE MAP IS TABLE OF BINARY_INTEGER
INDEX BY VARCHAR2 (10);

ling_jiu_map MAP;
shibaiqian_map MAP;
wanyizhao_map MAP;
--临时变量
i INT := 0; --'临时变量
j INT := 0; --临时变量
k INT := 0; --临时变量
x INT := 0; --临时变量
y INT := 0; --临时变量
str VARCHAR2 (100) := ''; --临时变量
tmp INT := 0; --临时变量
tmp2 INT := 0; --临时变量
integer_part VARCHAR2 (100) := ''; --数字形式整数部分
float_part VARCHAR2 (100) := ''; --数字形式小数部分
returnvalue NUMBER := 0; --返回值
BEGIN --初始化数组
ling_jiu_map ('零') := 0;
ling_jiu_map ('一') := 1;
ling_jiu_map ('二') := 2;
ling