在財務系統開發中,將數字金額轉換為中文大寫格式(如「壹佰貳拾叁元整」)是常見需求。雖然 Oracle 資料庫有現成函數,但 SQL Server 內建並無此功能。本文將分享一個從 Oracle 移植而來的 T-SQL 純量值函數 dbo.L2U,能將 numeric(15,2) 金額轉為符合會計習慣的大寫字串。
CREATE FUNCTION dbo.L2U (
@n_LowerMoney numeric(15,2), -- 小寫金額,支援至兆級、兩位小數
@v_TransType int -- 轉換模式:0=語意轉換(含「整」、「零」處理),1=直譯模式
) RETURNS varchar(200)
ROUND 四捨五入至兩位小數,並 LTRIM/RTRIM 移除空白。REPLACE 清理冗餘「零」、合併單位(如「零角零分」→「整」、「零億零萬零元」→「億元」),並處理「壹元以下」開頭字元修剪。CREATE FUNCTION dbo.L2U (@n_LowerMoney numeric(15,2), @v_TransType int)
RETURNS VARCHAR(200) AS
BEGIN
DECLARE @v_LowerStr VARCHAR(200), @v_UpperPart VARCHAR(200), @v_UpperStr VARCHAR(200), @i_I INT;
SET @v_LowerStr = LTRIM(RTRIM(ROUND(@n_LowerMoney,2)));
SET @i_I = 1;
SET @v_UpperStr = '';
WHILE (@i_I <= LEN(@v_LowerStr))
BEGIN
SELECT @v_UpperPart =
CASE SUBSTRING(@v_LowerStr, LEN(@v_LowerStr) - @i_I + 1, 1)
WHEN '.' THEN '元'
WHEN '0' THEN '零'
WHEN '1' THEN '壹'
WHEN '2' THEN '貳'
WHEN '3' THEN '參'
WHEN '4' THEN '肆'
WHEN '5' THEN '伍'
WHEN '6' THEN '陸'
WHEN '7' THEN '柒'
WHEN '8' THEN '捌'
WHEN '9' THEN '玖'
END
+
CASE @i_I
WHEN 1 THEN '分'
WHEN 2 THEN '角'
WHEN 3 THEN '元'
WHEN 4 THEN '拾'
WHEN 5 THEN '佰'
WHEN 6 THEN '仟'
WHEN 7 THEN '萬'
WHEN 8 THEN '拾'
WHEN 9 THEN '佰'
WHEN 10 THEN '仟'
WHEN 11 THEN '億'
WHEN 12 THEN '拾'
WHEN 13 THEN '佰'
WHEN 14 THEN '仟'
WHEN 15 THEN '萬'
ELSE ''
END;
SET @v_UpperStr = @v_UpperPart + @v_UpperStr;
SET @i_I = @i_I + 1;
END
IF (0 = @v_TransType)
BEGIN
SET @v_UpperStr = REPLACE(@v_UpperStr, '零拾', '零');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零佰', '零');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零仟', '零');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零零零', '零');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零零', '零');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零角零分', '整');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零分', '整');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零角', '零');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零億零萬零元', '億元');
SET @v_UpperStr = REPLACE(@v_UpperStr, '億零萬零元', '億元');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零億零萬', '億');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零萬零元', '萬元');
SET @v_UpperStr = REPLACE(@v_UpperStr, '萬零元', '萬元');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零億', '億');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零萬', '萬');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零元', '元');
SET @v_UpperStr = REPLACE(@v_UpperStr, '零零', '零');
END
-- 處理小於 1 元的開頭字元
IF ('元' = SUBSTRING(@v_UpperStr, 1, 1)) SET @v_UpperStr = SUBSTRING(@v_UpperStr, 2, LEN(@v_UpperStr) - 1);
IF ('零' = SUBSTRING(@v_UpperStr, 1, 1)) SET @v_UpperStr = SUBSTRING(@v_UpperStr, 2, LEN(@v_UpperStr) - 1);
IF ('角' = SUBSTRING(@v_UpperStr, 1, 1)) SET @v_UpperStr = SUBSTRING(@v_UpperStr, 2, LEN(@v_UpperStr) - 1);
IF ('分' = SUBSTRING(@v_UpperStr, 1, 1)) SET @v_UpperStr = SUBSTRING(@v_UpperStr, 2, LEN(@v_UpperStr) - 1);
IF ('整' = SUBSTRING(@v_UpperStr, 1, 1)) SET @v_UpperStr = '零元整';
RETURN @v_UpperStr;
END
-- 語意模式(推薦)
SELECT dbo.L2U(56588441.111, 0); -- 輸出:伍仟陸佰伍拾捌萬捌仟肆佰肆拾壹元壹角壹分
SELECT dbo.L2U(0.00, 0); -- 輸出:零元整
-- 直譯模式
SELECT dbo.L2U(123.45, 1); -- 輸出:壹佰貳拾參元肆角伍分
999,999,999,999.99(兆級),超過範圍請擴充 numeric 精度與單位邏輯。