© 2020, Developed by Hieu Dev

Hàm định dạng số thành chữ tiếng Anh và tiếng Việt trong SQL Server

Hôm nay, mình sẽ chia sẻ các bạn hàm định dạng số thành chữ tiếng Anh và tiếng Việt trong cơ sở dữ liệu SQL Server thông dụng và dễ hiểu nhất.


Ví dụ: Khi chúng ta nhập vào số 123456789 thì kết quả convert như sau:
  • Tiếng Anh: One hundred twenty three million four hundred fifty six thousand seven hundred eighty nine
  • Tiếng Việt: Một trăm hai mươi ba triệu bốn trăm năm mươi sáu nghìn bảy trăm tám mươi chín
Và 2 kết quả trên đều được mình copy khi thực hiện execute hàm scalar function trong cơ sở dữ liệu SQL Server, và cụ thể code sau:

Định dạng số thành chữ tiếng Anh

Đây là code convert, sau khi tạo hàm xong, để thực thi bạn chạy lệnh sau: 
SELECT dbo.fn_docsothanhchu_EN(123456789)

SET QUOTED_IDENTIFIER ON;
SET ANSI_NULLS ON;
GO

CREATE FUNCTION dbo.fn_docsothanhchu_EN
(
    @amount FLOAT
)
RETURNS VARCHAR(100)
AS
BEGIN
    DECLARE @NumberEnglish TABLE
    (
        [NumberValue] INT,
        [NumberString] VARCHAR(100)
    );
    INSERT INTO @NumberEnglish
    (
        [NumberValue],
        [NumberString]
    )
    VALUES
    (0, ''),
    (1, 'One'),
    (2, 'Two'),
    (3, 'Three'),
    (4, 'Four'),
    (5, 'Five'),
    (6, 'Six'),
    (7, 'Seven'),
    (8, 'Eight'),
    (9, 'Nine'),
    (10, 'Ten'),
    (11, 'Eleven'),
    (12, 'Twelve'),
    (13, 'Thirteen'),
    (14, 'Fourteen'),
    (15, 'Fifteen'),
    (16, 'Sixteen'),
    (17, 'Seventeen'),
    (18, 'Eighteen'),
    (19, 'Nineteen'),
    (20, 'Twenty'),
    (30, 'Thirty'),
    (40, 'Forty'),
    (50, 'Fifty'),
    (60, 'Sixty'),
    (70, 'Seventy'),
    (80, 'Eighty'),
    (90, 'Ninety'),
    (100, 'One Hundred'),
    (1000, 'Thousand'),
    (1000000, 'Million'),
    (1000000000, 'Billion');


    DECLARE @orig_amt FLOAT;
    DECLARE @factor FLOAT;
    DECLARE @str_amount VARCHAR(500);
    DECLARE @mod INT;
    SET @orig_amt = @amount;
    SET @factor = 1000000000;
    SET @str_amount = '';


    WHILE @amount > 0.00
    BEGIN
        IF @amount > 0.0
           AND @amount < 1.0
        BEGIN
            IF @str_amount <> ''
                SET @str_amount = @str_amount + ' and ';
            SET @str_amount = @str_amount + CONVERT(VARCHAR, CONVERT(INT, @amount * 100)) + '/100';
            SET @amount = 0.00;
        END;
        ELSE
        BEGIN

            SET @mod = CONVERT(INT, @amount) / @factor;

            IF @mod <= 20
            BEGIN
                SELECT @str_amount = @str_amount + ' ' + NumberString
                FROM @NumberEnglish
                WHERE NumberValue = @mod;
            END;
            IF @mod > 20
               AND @mod <= 99
            BEGIN
                SELECT @str_amount = @str_amount + ' ' + NumberString
                FROM @NumberEnglish
                WHERE NumberValue = (@mod / 10) * 10;
                SELECT @str_amount = @str_amount + ' ' + NumberString
                FROM @NumberEnglish
                WHERE NumberValue = @mod % 10;
            END;

            IF @mod > 99
            BEGIN
                SELECT @str_amount = @str_amount + ' ' + NumberString + ' Hundred'
                FROM @NumberEnglish
                WHERE NumberValue = @mod / 100;

                IF @mod % 100 <= 20
                BEGIN
                    SELECT @str_amount = @str_amount + ' ' + NumberString
                    FROM @NumberEnglish
                    WHERE NumberValue = @mod % 100;
                END;
                ELSE
                BEGIN
                    SELECT @str_amount = @str_amount + ' ' + NumberString
                    FROM @NumberEnglish
                    WHERE NumberValue = (@mod % 100 / 10) * 10;
                    SELECT @str_amount = @str_amount + ' ' + NumberString
                    FROM @NumberEnglish
                    WHERE NumberValue = @mod % 10;
                END;
            END;

            IF @factor > 1
               AND @str_amount <> ''
            BEGIN
                SELECT @str_amount = @str_amount + ' ' + NumberString
                FROM @NumberEnglish
                WHERE NumberValue = @factor;
            END;
            SELECT @amount = @amount - @factor * @mod;
            IF @str_amount <> ''
               AND @amount >= 1.0
               AND @factor > 1
                SELECT @str_amount = @str_amount + ',';
            SET @factor = @factor / 1000;
        END;
    END;
    IF @str_amount = ''
        SET @str_amount = 'Zero';
    SET @str_amount = REPLACE(LTRIM(@str_amount), '  ', ' ');
    SET @str_amount = REPLACE(LTRIM(@str_amount), ', ', ' ');
    SET @str_amount = LOWER(@str_amount);
    IF @str_amount <> ''
        SET @str_amount = UPPER(LEFT(@str_amount, 1)) + RIGHT(@str_amount, LEN(@str_amount) - 1);
    RETURN (@str_amount);

END;

GO


Có rất nhiều cách để thực hiện định dạng chuyển đổi, nhưng các trên rất rõ ràng và dễ hiểu và tối ưu nhất.

Định dạng số thành chữ tiếng Việt

Chuyển đổi sang tiếng Việt đôi chút phức tạp hơn vì có các trường hợp ta cần phải control được, ví dụ như mươi năm, mươi nhăm, mươi mốt, mười bốn, linh bốn, linh tư,... Chưa code đã thấy bắt đầu rối rồi nhỉ, hãy tham khảo code sau, và truy vấn bằng các chạy lệnh:
SELECT dbo.fn_docsothanhchu_EN(123456789)

CREATE FUNCTION [dbo].[Num2Text](@Number int)
RETURNS nvarchar(4000) AS 
BEGIN 

DECLARE @sNumber nvarchar(4000)
DECLARE @Return	nvarchar(4000)
DECLARE @mLen int
DECLARE @i int

DECLARE @mDigit int
DECLARE @mGroup int
DECLARE @mTemp nvarchar(4000)
DECLARE @mNumText nvarchar(4000)

SELECT @sNumber=LTRIM(STR(@Number))
SELECT @mLen = Len(@sNumber)

SELECT @i=1
SELECT @mTemp=''

WHILE @i <= @mLen
BEGIN

SELECT @mDigit=SUBSTRING(@sNumber, @i, 1)

IF @mDigit=0 SELECT @mNumText=N'không'
ELSE
BEGIN
IF @mDigit=1 SELECT @mNumText=N'một'
ELSE
IF @mDigit=2 SELECT @mNumText=N'hai'
ELSE
IF @mDigit=3 SELECT @mNumText=N'ba'
ELSE
IF @mDigit=4 SELECT @mNumText=N'bốn'
ELSE
IF @mDigit=5 SELECT @mNumText=N'năm'
ELSE
IF @mDigit=6 SELECT @mNumText=N'sáu'
ELSE
IF @mDigit=7 SELECT @mNumText=N'bảy'
ELSE
IF @mDigit=8 SELECT @mNumText=N'tám'
ELSE
IF @mDigit=9 SELECT @mNumText=N'chín'
END

SELECT @mTemp = @mTemp + ' ' + @mNumText

IF (@mLen = @i) BREAK

Select @mGroup=(@mLen - @i) % 9

IF @mGroup=0
BEGIN
SELECT @mTemp = @mTemp + N' tỷ'

If SUBSTRING(@sNumber, @i + 1, 3) = N'000' 
SELECT @i = @i + 3

If SUBSTRING(@sNumber, @i + 1, 3) = N'000' 
SELECT @i = @i + 3

If SUBSTRING(@sNumber, @i + 1, 3) = N'000' 
SELECT @i = @i + 3
END 
ELSE
IF @mGroup=6
BEGIN
SELECT @mTemp = @mTemp + N' triệu'

If SUBSTRING(@sNumber, @i + 1, 3) = N'000' 
SELECT @i = @i + 3

If SUBSTRING(@sNumber, @i + 1, 3) = N'000' 
SELECT @i = @i + 3
END
ELSE
IF @mGroup=3
BEGIN
SELECT @mTemp = @mTemp + N' nghìn'

If SUBSTRING(@sNumber, @i + 1, 3) = N'000' 
SELECT @i = @i + 3

END
ELSE
BEGIN

Select @mGroup=(@mLen - @i) % 3

IF @mGroup=2	
SELECT @mTemp = @mTemp + N' trăm'
ELSE
IF @mGroup=1
SELECT @mTemp = @mTemp + N' mươi'	
END


SELECT @i=@i+1
END

--'Loại bỏ trường hợp x00

SELECT @mTemp = Replace(@mTemp, N'không mươi không', '')

--'Loại bỏ trường hợp 00x

SELECT @mTemp = Replace(@mTemp, N'không mươi ', N'linh ')

--'Loại bỏ trường hợp x0, x>=2

SELECT @mTemp = Replace(@mTemp, N'mươi không', N'mươi')

--'Fix trường hợp 10

SELECT @mTemp = Replace(@mTemp, N'một mươi', N'mười')

--'Fix trường hợp x4, x>=2

SELECT @mTemp = Replace(@mTemp, N'mươi bốn', N'mươi tư')

--'Fix trường hợp x04 

SELECT @mTemp = Replace(@mTemp, N'linh bốn', N'linh tư')

--'Fix trường hợp x5, x>=2

SELECT @mTemp = Replace(@mTemp, N'mươi năm', N'mươi nhăm')

--'Fix trường hợp x1, x>=2

SELECT @mTemp = Replace(@mTemp, N'mươi một', N'mươi mốt')

--'Fix trường hợp x15

SELECT @mTemp = Replace(@mTemp, N'mười năm', N'mười lăm')

--'Bỏ ký tự space

SELECT @mTemp = LTrim(@mTemp)

--'Ucase ký tự đầu tiên

SELECT @Return=UPPER(Left(@mTemp, 1)) + SUBSTRING(@mTemp,2, 4000)

RETURN @Return
END

Mong 2 hàm sau hữu ích với các bạn trong việc áp dụng trong công việc và học tập. Chúc các bạn thành công!

Tham khảo: laptrinhvb.netHiếu Quốc.

2 Nhận xét

Mới hơn Cũ hơn