sqlserver实现数字转人民币大写

意义

主要是自己无聊,写一个大家常用到sql自定义函数,练练手。

环境

sql sever数据库,其他数据没试过

思路

把输入值分出两部分:整数+小数(例如:1234566.12元,输出:壹佰贰拾叁万肆仟伍佰陆拾陆壹角贰分,所以分成两部分处理简单)。

步骤:用Cast()获取整数部分--->ConverToIntRMB()函数处理整数--->ConverToDecimalRMB()函数处理小数

整数部分

创建两张表digits,unit,digits用来存储大写数字;unit用来存储单位:
digits表:

DigitChinese
1
2
3

unit表:

UnitPositionUnitName
1‘’
2‘拾’
3‘佰’

用取余和除数取整调动输入值的位数

input = 123461 
digit = input % 10 //获取个位值1
input = input / 10 //移位,input值变为12346

小数部分

其实差不多,digits表一样,unit表变成"角,分",不多解释。

代码部分

CREATE FUNCTION dbo.ConvertToIntRMB(@input DECIMAL(18,2))
RETURNS NVARCHAR(MAX)
AS
BEGIN
	--声明三个变量@result:函数返回;@digits:存放映射关系;@unit:存放单位
	DECLARE @result NVARCHAR(MAX) = '';
	DECLARE @digits TABLE (Digit INT, Chinese NVARCHAR(10));
	DECLARE @unit TABLE (UnitPosition INT, UnitName NVARCHAR(10));
	DECLARE @unit2 TABLE (UnitPosition INT, UnitName NVARCHAR(10));
	--给表插入数据
	INSERT INTO @digits (Digit, Chinese)
	VALUES
		(0, '零'), (1, '壹'), (2, '贰'), (3, '叁'), (4,'肆'), (5, '伍'),(6, '陆'), (7, '柒'), (8, '捌'), (9, '玖');
		
	INSERT INTO	@unit (UnitPosition, UnitName)
	VALUES
		(1, ''), (2, '拾'), (3, '佰'), (4, '仟'), (5, '万'), (6, '拾万'), (7, '佰万'), (8, '仟万'), (9, '亿');
		
	INSERT INTO	@unit2 (UnitPosition, UnitName)
	VALUES
		(1, '分'), (2, '角');
	--@position:记录位置用于获取单位
	DECLARE @position INT = 1;
	--@intNum:整数部分
	DECLARE @intNum INT = CAST(@input AS INT);
	--@decimalNum:小数部分
	DECLARE @decimalNum INT = CAST((@input - @intNum) * 100 AS INT);
	
	--开始逻辑部分
	IF @intNum = 0
	BEGIN
		IF @decimalNum = 0
		BEGIN
			SET @result = '零元';
		END
		--只有小数部分
		ELSE BEGIN
			--小数记录位置用于获取单位
			DECLARE @position2 INT = 1;
			WHILE @decimalNum > 0
	   		BEGIN
		    	--拿出个位
		        DECLARE @digit2 INT = @decimalNum % 10;
		        --小数点左移一位
		        SET @decimalNum = @decimalNum / 10;
				--根据记录位置获取单位
				DECLARE @unitName2 NVARCHAR(10) = (SELECT UnitName FROM @unit2 WHERE UnitPosition = @position2);
				--小写转换大写
				DECLARE @chineseDigit2 NVARCHAR(10) = (SELECT Chinese FROM @digits WHERE Digit = @digit2);
				--@position < 3防止跑出去
				IF @digit2 > 0 AND @position < 3 
				BEGIN
		        	SET @result = @chineseDigit2 + @unitName2 + @result;
		        END
		        SET @position2 = @position2 + 1;
			END    
    END
	END
	--整数部分
	ELSE BEGIN
		--拿出个位,用于决定最后加上元还是元整
		DECLARE @firstNum INT = @intNum % 10;
		WHILE @IntNum > 0
		BEGIN
			--拿出个位
			DECLARE @digit INT = @intNum % 10;
			--整数部分小数点左移一位
			SET @intNum = @intNum / 10;
			--根据记录位置获取单位
			DECLARE @unitName NVARCHAR(10) = (SELECT UnitName FROM @unit WHERE UnitPosition = @position);
			--小写转换大写
			DECLARE @chineseDigit NVARCHAR(10) = (SELECT Chinese FROM @digits WHERE Digit = @digit);
			--给@result赋值
			IF @digit > 0
            BEGIN
                SET @result = @chineseDigit + @unitName + @result;
            END
			--单位增大
            SET @position = @position + 1;
        END
        --整数部分最后加上元或元整
		SET @result = @result + '元';
		IF @firstNum = 0 AND @decimalNum = 0
        BEGIN 
        	SET @result = @result + '整';
        END
    END
    --小数部分
    IF @decimalNum > 0 
    BEGIN
    	--小数记录位置用于获取单位
		DECLARE @position3 INT = 1;
		--记录小数
		DECLARE @decimalResult NVARCHAR(500)= '';
		WHILE @decimalNum > 0
	   	BEGIN
			--拿出个位
		    DECLARE @digit3 INT = @decimalNum % 10;
		    --小数点左移一位
		    SET @decimalNum = @decimalNum / 10;
			--根据记录位置获取单位
			DECLARE @unitName3 NVARCHAR(10) = (SELECT UnitName FROM @unit2 WHERE UnitPosition = @position3);
			--小写转换大写
			DECLARE @chineseDigit3 NVARCHAR(10) = (SELECT Chinese FROM @digits WHERE Digit = @digit3);
			--@position3 < 3防止跑出去
			IF @digit3 > 0 AND @position3 < 3 
			BEGIN
		        SET @decimalResult = @chineseDigit3 + @unitName3 + @decimalResult;
		    END
		    SET @position3 = @position3 + 1;
		END
		SET @result = @result + @decimalResult;
    END
    
    RETURN @result;
END;

代码大概如此没有过多优化,小数处理部分代码重复,就这样吧。

后记

纯text手工打,懒得上sql sever,可能有bug,思路就是:0一种情况,纯整数一种情况,纯小数一种情况,整数和小数混杂一种情况,中间忘记个位为零时候单位是“元整”而非“元”。
优化思路:整数一个函数,小数一个函数,在整数函数中调用小数函数,解决代码重复问题,同时还能提高效率。
下次见!

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您解答这个问题。 Oracle中可以使用PL/SQL代码将数字换为人民币大写。以下是一个示例代码: ``` CREATE OR REPLACE FUNCTION f_num2rmb(p_num IN NUMBER) RETURN VARCHAR2 IS l_num NUMBER := TRUNC(p_num); l_dec NUMBER(2,0) := TRUNC(MOD(p_num, 1) * 100); l_rmb VARCHAR2(200); l_unit CONSTANT VARCHAR2(10) := '元'; l_decimal CONSTANT VARCHAR2(10) := '角分'; l_numstr CONSTANT VARCHAR2(50) := '零壹贰叁肆伍陆柒捌玖'; l_unitstr CONSTANT VARCHAR2(50) := '仟佰拾'; l_decimalstr CONSTANT VARCHAR2(50) := '分角'; BEGIN IF l_num = 0 AND l_dec = 0 THEN RETURN '零元整'; END IF; l_rmb := TO_CHAR(l_dec, 'FM00') || l_decimal; FOR i IN 1..4 LOOP l_unitstr := SUBSTR(l_unitstr, 2); IF l_num = 0 THEN EXIT; END IF; l_rmb := SUBSTR(l_numstr, MOD(TRUNC(l_num / POWER(10, (4 - i) * 4)), 10) + 1, 1) || l_unitstr || l_rmb; l_num := TRUNC(l_num / 10); END LOOP; l_rmb := REPLACE(l_rmb, '零仟', '零'); l_rmb := REPLACE(l_rmb, '零佰', '零'); l_rmb := REPLACE(l_rmb, '零拾', '零'); l_rmb := REPLACE(l_rmb, '零零零', '零'); l_rmb := REPLACE(l_rmb, '零零', '零'); l_rmb := REPLACE(l_rmb, '零角零分', '整'); IF SUBSTR(l_rmb, 1, 1) = '零' THEN l_rmb := SUBSTR(l_rmb, 2); END IF; RETURN l_rmb || l_unit || '整'; END; / ``` 使用该函数,可以将数字换为人民币大写。例如: ``` SELECT f_num2rmb(12345.67) FROM DUAL; ``` 输出结果为: ``` 壹万贰仟叁佰肆拾伍元陆角柒分整 ``` 这个函数的代码实现比较复杂,但是可以通过调用该函数来轻松地将数字换为人民币大写

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

战术级天朗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值