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

使用pg_background调用含raise notice函数时WIN1252编码报错求助

问题:pg_background扩展在Windows/PostgreSQL 15下的字符编码异常(与RAISE NOTICE相关)

环境与编码设置

当前客户端与服务器编码:

select current_setting('client_encoding'), current_setting('server_encoding');

输出:

current_setting | current_setting
-----------------+-----------------
 WIN1252         | UTF8
(1 row)

测试函数定义

创建两个测试函数,区别仅在于是否包含RAISE NOTICE语句:

create or replace function test_encoding_1() returns text language plpgsql as $$ begin raise notice 'Noël'; return 'Noël'; end $$;
create or replace function test_encoding_2() returns text language plpgsql as $$ begin return 'Noël'; end $$;

直接调用结果

直接调用两个函数均正常显示字符:

select test_encoding_1();

输出:

NOTICE:  Noël
 test_encoding_1
-----------------
 Noël
(1 row)

pg_background调用的异常表现

通过pg_background调用时,含RAISE NOTICE的函数报错,无该语句的函数正常:

select r from pg_background_result(pg_background_launch('select test_encoding_1()')) as t(r text);

报错:

ERROR:  invalid byte sequence for encoding "UTF8": 0xeb 0x6c

调用无RAISE NOTICE的函数正常:

select r from pg_background_result(pg_background_launch('select test_encoding_2()')) as t(r text);

输出:

r
------
 Noël
(1 row)

修改客户端编码为SQL_ASCII后的表现

设置客户端编码为SQL_ASCII后不再报错,但字符显示乱码:

set client_encoding to 'SQL_ASCII';

select r from pg_background_result(pg_background_launch('select test_encoding_1()')) as t(r text);

输出:

NOTICE:  Noël
   r
-------
 Noël
(1 row)
select r from pg_background_result(pg_background_launch('select test_encoding_2()')) as t(r text);

输出:

r
-------
 Noël
(1 row)

需求

是否可通过配置服务器、修改函数代码或其他方式,获取正确WIN1252字符集的结果?


解决方案

方法1:后台会话显式设置客户端编码

pg_background启动的后台会话默认继承服务器编码(UTF8),与当前客户端的WIN1252编码不一致,导致RAISE NOTICE的输出转码失败。在后台执行的SQL开头显式设置client_encoding为WIN1252即可:

select r from pg_background_result(pg_background_launch('SET client_encoding = ''WIN1252''; select test_encoding_1()')) as t(r text);

此方法让后台会话的编码与当前客户端对齐,RAISE NOTICE的输出会按WIN1252编码传递,可正常显示无报错。

方法2:修改函数,显式控制字符串编码

在函数中对RAISE NOTICE的字符串进行编码转换,确保后台会话输出的字节符合当前客户端编码要求:

create or replace function test_encoding_1() returns text language plpgsql as $$ 
begin 
  -- 将字符串转换为WIN1252编码的字节串后输出
  raise notice '%', convert_to('Noël', 'WIN1252'); 
  return 'Noël'; 
end $$;

修改后通过pg_background调用时,RAISE NOTICE输出的是WIN1252编码的字节,当前客户端可直接正确解析。

方法3:全局配置后台会话编码(可选)

若需所有pg_background会话默认使用WIN1252编码,可修改PostgreSQL的postgresql.conf,添加或调整:

client_encoding = 'WIN1252'

修改后需重启PostgreSQL服务。此方法会影响所有会话的默认编码,需根据实际场景评估是否适用。


内容的提问来源于stack exchange,提问作者Joël Hecht

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:28:12