You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写PostgreSQL函数实现数字转英法文单词?

解决方案

1. 基础版本(直接拼接所有数字位)

这个函数会把输入数字的每一位(包括小数部分)直接转换为对应语言的单词,无分隔标识:

CREATE OR REPLACE FUNCTION number_to_word_pairs(n numeric)
RETURNS TABLE(english text, french text) AS $$
DECLARE
    num_str text := REPLACE(n::text, '.', ''); -- 移除小数点,合并所有数字位
    eng_words text[];
    fra_words text[];
    digit char;
BEGIN
    FOREACH digit IN ARRAY regexp_split_to_array(num_str, '') LOOP
        -- 英文数字-单词映射
        eng_words := eng_words || CASE digit
            WHEN '0' THEN 'Zero'
            WHEN '1' THEN 'One'
            WHEN '2' THEN 'Two'
            WHEN '3' THEN 'Three'
            WHEN '4' THEN 'Four'
            WHEN '5' THEN 'Five'
            WHEN '6' THEN 'Six'
            WHEN '7' THEN 'Seven'
            WHEN '8' THEN 'Eight'
            WHEN '9' THEN 'Nine'
        END;
        
        -- 法文数字-单词映射(符合法语文习惯)
        fra_words := fra_words || CASE digit
            WHEN '0' THEN 'Zéro'
            WHEN '1' THEN 'Un'
            WHEN '2' THEN 'Deux'
            WHEN '3' THEN 'Trois'
            WHEN '4' THEN 'Quatre'
            WHEN '5' THEN 'Cinq'
            WHEN '6' THEN 'Six'
            WHEN '7' THEN 'Sept'
            WHEN '8' THEN 'Huit'
            WHEN '9' THEN 'Neuf'
        END;
    END LOOP;

    -- 数组转空格分隔的字符串
    english := array_to_string(eng_words, ' ');
    french := array_to_string(fra_words, ' ');

    RETURN NEXT;
END;
$$ LANGUAGE plpgsql;

测试示例:

-- 输入整数
SELECT * FROM number_to_word_pairs(123);
-- 输出:
-- english | One Two Three
-- french  | Un Deux Trois

-- 输入带小数的数字
SELECT * FROM number_to_word_pairs(123.00);
-- 输出:
-- english | One Two Three Zero Zero
-- french  | Un Deux Trois Zéro Zéro

2. 增强版本(区分整数与小数部分)

如果需要明确区分整数和小数部分,可使用这个版本(英文用point,法文用符合本土习惯的virgule):

CREATE OR REPLACE FUNCTION number_to_word_pairs_with_separator(n numeric)
RETURNS TABLE(english text, french text) AS $$
DECLARE
    num_parts text[] := string_to_array(n::text, '.');
    int_part text := num_parts[1];
    dec_part text := COALESCE(num_parts[2], ''); -- 无小数部分则为空字符串
    eng_int text[];
    eng_dec text[];
    fra_int text[];
    fra_dec text[];
    digit char;
BEGIN
    -- 处理整数部分
    FOREACH digit IN ARRAY regexp_split_to_array(int_part, '') LOOP
        eng_int := eng_int || CASE digit
            WHEN '0' THEN 'Zero'
            WHEN '1' THEN 'One'
            WHEN '2' THEN 'Two'
            WHEN '3' THEN 'Three'
            WHEN '4' THEN 'Four'
            WHEN '5' THEN 'Five'
            WHEN '6' THEN 'Six'
            WHEN '7' THEN 'Seven'
            WHEN '8' THEN 'Eight'
            WHEN '9' THEN 'Nine'
        END;
        
        fra_int := fra_int || CASE digit
            WHEN '0' THEN 'Zéro'
            WHEN '1' THEN 'Un'
            WHEN '2' THEN 'Deux'
            WHEN '3' THEN 'Trois'
            WHEN '4' THEN 'Quatre'
            WHEN '5' THEN 'Cinq'
            WHEN '6' THEN 'Six'
            WHEN '7' THEN 'Sept'
            WHEN '8' THEN 'Huit'
            WHEN '9' THEN 'Neuf'
        END;
    END LOOP;

    -- 处理小数部分(如果存在)
    IF dec_part != '' THEN
        FOREACH digit IN ARRAY regexp_split_to_array(dec_part, '') LOOP
            eng_dec := eng_dec || CASE digit
                WHEN '0' THEN 'Zero'
                WHEN '1' THEN 'One'
                WHEN '2' THEN 'Two'
                WHEN '3' THEN 'Three'
                WHEN '4' THEN 'Four'
                WHEN '5' THEN 'Five'
                WHEN '6' THEN 'Six'
                WHEN '7' THEN 'Seven'
                WHEN '8' THEN 'Eight'
                WHEN '9' THEN 'Nine'
            END;
            
            fra_dec := fra_dec || CASE digit
                WHEN '0' THEN 'Zéro'
                WHEN '1' THEN 'Un'
                WHEN '2' THEN 'Deux'
                WHEN '3' THEN 'Trois'
                WHEN '4' THEN 'Quatre'
                WHEN '5' THEN 'Cinq'
                WHEN '6' THEN 'Six'
                WHEN '7' THEN 'Sept'
                WHEN '8' THEN 'Huit'
                WHEN '9' THEN 'Neuf'
            END;
        END LOOP;

        -- 拼接带分隔符的结果
        english := array_to_string(eng_int, ' ') || ' point ' || array_to_string(eng_dec, ' ');
        french := array_to_string(fra_int, ' ') || ' virgule ' || array_to_string(fra_dec, ' ');
    ELSE
        -- 无小数部分直接返回整数结果
        english := array_to_string(eng_int, ' ');
        french := array_to_string(fra_int, ' ');
    END IF;

    RETURN NEXT;
END;
$$ LANGUAGE plpgsql;

测试示例:

SELECT * FROM number_to_word_pairs_with_separator(123.00);
-- 输出:
-- english | One Two Three point Zero Zero
-- french  | Un Deux Trois virgule Zéro Zéro

为什么单独的ZeroToNine函数不够?

你之前写的ZeroToNine仅处理单个数字的转换,但需求需要遍历输入数字的每一位(包括整数和小数部分的所有数字),并将所有转换后的单词拼接成完整字符串。上述方案通过遍历拆分后的每个数字字符,逐个映射并收集结果,最终满足需求。

内容的提问来源于stack exchange,提问作者Cool Name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:05:01