CREATE OR REPLACE FUNCTION num_to_cn_capital(amount IN NUMBER)
RETURN VARCHAR2 IS
-- 定义数字和对应大写
nums VARCHAR2(30) := '零壹贰叁肆伍陆柒捌玖'; --10*3
units VARCHAR2(39) := '万仟佰拾亿仟佰拾万仟佰拾元'; --13*3
small_cents VARCHAR2(6) := '角分';
strnum VARCHAR2(1000);
result_amount VARCHAR2(4000) := '';
part VARCHAR2(1000);
digit NUMBER(25, 6);
unit_pos INTEGER;
BEGIN
IF amount < 0 THEN
RETURN '负' || num_to_cn_capital(-amount);
END IF;
-- 转换整数部分
strnum := to_char(round(floor(amount)));
IF strnum = '0' THEN
result_amount := '零';
ELSE
IF strnum IS NOT NULL THEN
FOR i IN REVERSE 1 .. length(strnum) LOOP
part := substr(strnum, length(strnum) + 1 - i, 1);
digit := to_number(part);
unit_pos := length(units) - i;
result_amount := result_amount || substr(nums, digit + 1, 1) ||
substr(units, unit_pos + 1, 1);
END LOOP;
ELSE
result_amount := '零';
END IF;
END IF;
result_amount := REPLACE(result_amount, '元', '');
result_amount := REPLACE(result_amount, '拾零', '拾');
result_amount := REPLACE(result_amount, '佰零', '佰');
result_amount := REPLACE(result_amount, '仟零', '仟');
result_amount := REPLACE(result_amount, '佰拾', '佰');
result_amount := REPLACE(result_amount, '仟佰', '仟');
-- 转换小数部分
part := round((amount - floor(amount)) * 100);
IF part != 0 THEN
result_amount := result_amount || '.';
strnum := to_char(part);
IF length(strnum) = 1 THEN
result_amount := result_amount || '零';
END IF;
FOR i IN 1 .. length(strnum) LOOP
digit := to_number(substr(strnum, i, 1));
result_amount := result_amount ||
REPLACE(substr(nums, digit + 1, 1), '零', '');
--SUBSTR(small_cents, i, 1) 角分
END LOOP;
END IF;
RETURN result_amount;
END;
示例(函数不含角分,可自行添加)
SELECT num_to_cn_capital(738829.70) from dual
输出结果
柒拾叁万捌仟捌佰贰拾玖.柒
含单位的金额大写
CREATE OR REPLACE FUNCTION num_to_cn_capital_dw(amount IN NUMBER)
RETURN VARCHAR2 IS
-- 定义数字和对应大写
nums VARCHAR2(30) := '零壹贰叁肆伍陆柒捌玖'; --10*3
units VARCHAR2(39) := '万仟佰拾亿仟佰拾万仟佰拾圆'; --13*3
small_cents VARCHAR2(6) := '角分';
strnum VARCHAR2(1000);
result_amount VARCHAR2(4000) := '';
part VARCHAR2(1000);
digit NUMBER(25, 6);
unit_pos INTEGER;
BEGIN
IF amount < 0 THEN
RETURN '负' || num_to_cn_capital_dw(-amount);
END IF;
-- 转换整数部分
strnum := to_char(round(floor(amount)));
IF strnum = '0' THEN
result_amount := '零';
ELSE
IF strnum IS NOT NULL THEN
FOR i IN REVERSE 1 .. length(strnum) LOOP
part := substr(strnum, length(strnum) + 1 - i, 1);
digit := to_number(part);
unit_pos := length(units) - i;
result_amount := result_amount || substr(nums, digit + 1, 1) ||
substr(units, unit_pos + 1, 1);
END LOOP;
ELSE
result_amount := '零';
END IF;
END IF;
--result_amount := REPLACE(result_amount, '元', '');
result_amount := REPLACE(result_amount, '拾零', '拾');
result_amount := REPLACE(result_amount, '佰零', '佰');
result_amount := REPLACE(result_amount, '仟零', '仟');
result_amount := REPLACE(result_amount, '佰拾', '佰');
result_amount := REPLACE(result_amount, '仟佰', '仟');
-- 转换小数部分
part := round((amount - floor(amount)) * 100);
IF part != 0 THEN
strnum := to_char(part);
IF length(strnum) = 1 THEN
result_amount := result_amount || '零';
END IF;
FOR i IN 1 .. length(strnum) LOOP
digit := to_number(substr(strnum, i, 1));
result_amount := result_amount ||
REPLACE(substr(nums, digit + 1, 1), '零', '') ||
substr(small_cents, i, 1);
--SUBSTR(small_cents, i, 1) 角分
END LOOP;
END IF;
RETURN result_amount;
END;
示例
SELECT num_to_cn_capital_dw(21544.92) from dual
输出结果
贰万壹仟伍佰肆拾肆圆玖角贰分