如何使用 PostgreSQL 处理特殊字符

how to treat special characters with postgresql

提问人:Guilherme Rodrigues 提问时间:10/2/2023 更新时间:10/2/2023 访问量:43

问:

我有一个使用 postgresql (plpgsql) 的函数,它使用 sendgrid api 发送电子邮件,这封电子邮件的内容是一个 .csv 文件,包含产品名称等。

电子邮件发送成功,过程进行得很顺利,但特殊字符以意想不到的方式处理 例如,我有一个产品叫做:

ÓLEO 柴油机

在我的 .csv 文件中,它被视为:

“LEO 柴油 B S10

问题出在特殊字符上。

我通过在记事本 ++ 中打开我的 .csv 文件进行了测试,我将文件转换为 utf-8-bom,在我的 excel 中重新打开它并且正确列出了特殊字符,我的问题是:如何将文件转换为 utf-8-good?或者如果有人有更好的方法来处理特殊角色并想介绍我,我将不客气。

我的职能:

CREATE OR REPLACE FUNCTION public.f_email_cotacao(premetente json, pdestinatario json, prespostapara json, passunto text, pconteudo json, pdatacotacao date DEFAULT CURRENT_DATE, pidempresa integer[] DEFAULT ARRAY[0])
 RETURNS void
 LANGUAGE plpgsql
 IMMUTABLE
AS $function$
DECLARE
    VVariavelGenerica                   RECORD;
BEGIN
    SELECT ARRAY_AGG(vc.id_empresa) 
    INTO pidempresa
    FROM vw vc
    WHERE vc.registro_ativo;

    WITH sub_arquivos AS (
        WITH sub_arquivo AS (
            SELECT 
                CONCAT(TO_CHAR(CURRENT_TIMESTAMP, 'YYYYMMDD_HH24MI'), '.csv') nome_arquivo,
                 TRANSLATE(ENCODE(CONVERT_TO(
                    CONCAT(E'Data Cotacao;Fornecedor;Produto;Empresa;Tipo Frete;Preco;Frete;Valor Unitario\n'
                        , ARRAY_TO_STRING(ARRAY_AGG(
                            CONCAT_WS(';' 
                                    , TO_CHAR(vc.data_cotacao, 'DD/MM/YYYY') 
                                    , TRIM(vc.fornecedor)
                                    , vc.produto 
                                    , vc.empresa 
                                    , vc.tipo_frete 
                                    , TRIM(vc.preco_unitario)
                                    , vc.valor_frete
                                    , vc.valor_unitario
                            )
                        ), E'\n')
                    ), 'UTF8'), 'base64'), E'\n', '') conteudo_arquivo  
            FROM vw_cotacao vc
            WHERE vc.data_cotacao = PDataCotacao
            AND (vc.id_empresa = ANY(PIdEmpresa) OR PIdEmpresa[1] = 0)
        )
        SELECT
            JSON_BUILD_OBJECT(
                'type', 'text/plain'
                , 'filename', sub.nome_arquivo 
                , 'content',  sub.conteudo_arquivo
                , 'disposition', 'attachment'
            ) arquivo_json
        FROM    sub_arquivo sub
    ), sub_email AS (
        SELECT  
            JSON_BUILD_OBJECT(
                'Authorization', 'my-token'
                , 'Content-Type', 'application/json'
            ) headers
            , JSON_BUILD_OBJECT(
                'from', PRemetente
                , 'personalizations', JSON_BUILD_ARRAY(JSON_BUILD_OBJECT('to', PDestinatario))
                , 'reply_to', PRespostaPara
                -- reply_to_list, JSON_BUILD_ARRAY(PRespostaPara)
                , 'subject', PAssunto
                , 'content', PConteudo
                , 'attachments', JSON_AGG(sub.arquivo_json)
                , 'tracking_settings', 
                    JSON_BUILD_OBJECT(
                        '', JSON_BUILD_OBJECT('enable', TRUE, '', TRUE)
                        , 'open_tracking', JSON_BUILD_OBJECT('', TRUE, 'substitution_tag', '%open-%')
                        , '', JSON_BUILD_OBJECT('', TRUE)
                    )
            ) body
        FROM    sub_arquivos sub
    )
    SELECT  *
    INTO    VVariavelGenerica
    FROM    sub_email sub, f_request_http(
            'POST', -- metodo 
            '', -- url 
            CAST(sub.headers AS TEXT),
            CAST(sub.body AS TEXT)
        );
        
    RAISE NOTICE '%', VVariavelGenerica;
END;
  $function$
;

SELECT * FROM public.f_email_cotacao(
        JSON_BUILD_OBJECT('email', '..', ', '.. ') 
        , JSON_BUILD_ARRAY(
            JSON_BUILD_OBJECT('', '...', ' ')
                ) 
        , CAST(CONCAT('..', .., 'DD/MM/YYYY HH24:MI:SS')) AS TEXT)
        , JSON_BUILD_ARRAY(
            JSON_BUILD_OBJECT(
                'type', 'text/plain'
                , 'value', '..'
            ) 
        ) -- content
);

PostgreSQL PLPGSQL SendGrid Sendmail

评论

0赞 Andrew Morton 10/2/2023
如果使用 UTF-16 对文件进行编码,Excel 是否能正确读取文件?
0赞 Guilherme Rodrigues 10/2/2023
嗨,我将文件保存为:UTF-16 BE,它有效,但我的数据报价标头带有这个额外的单词:þÿ 结尾如下:þÿQuote Date @AndrewMorton
0赞 Andrew Morton 10/2/2023
你能试试UTF-16LE吗?稍微相关:为什么 Windows 使用 UTF-16LE?
0赞 Guilherme Rodrigues 10/2/2023
我按照你的要求做了,结果是成功的。只有一个问题,我的文件丢失了它的列(A 列中的日期,B 列中的供应商等),这是客户要求。并开始在一列中呈现所有内容@AndrewMorton
0赞 hackwithharsha 10/2/2023
你试过 E'' 符号吗?

答: 暂无答案