瀚高数据库 22001 字符串超长错误
错误原文:22001: value too long for type character varying(xx byte)
报错原因:varchar 字段在瀚高数据库中是按字节校验,中文 / 全角字符占用字节多,内容超出字段字节上限。
一、核心原理
瀚高默认
nls_length_semantics = byte:varchar(n)按字节限制英文字符:1 字节 / 个
UTF8 中文:3 字节 / 个
例:
varchar(12)最多存 4 个中文标准 PostgreSQL 按字符限制,这是两者差异,也是报错根源。
二、三类解决方案(按推荐优先级排序)
方案 1:全局统一为「按字符」(根治,推荐)
修改全局参数,全库对齐 PG 行为,一劳永逸。
-- 1. 设置全局默认按字符计算
ALTER SYSTEM SET nls_length_semantics = 'char';
-- 2. 重载参数(无需重启数据库)
SELECT pg_reload_conf();
-- 3. 当前会话即时生效
SET nls_length_semantics = 'char';
-- 4. 校验配置
SHOW nls_length_semantics;✅ 效果:后续所有库、新建表的 varchar(n) 均按字符计数,和 PG 完全一致。
方案 2:单库单独设置(仅指定库生效)
不想改动全局,只针对业务库配置:
-- 连接目标数据库后执行
ALTER DATABASE 库名 SET nls_length_semantics = 'char';
-- 临时让当前会话生效
SET nls_length_semantics = 'char';✅ 效果:仅该数据库内 varchar 按字符计算,其他库保持原有规则。
方案 3:修改已有表字段长度(应急修复存量表)
已存在的表、不方便改参数时,直接扩大字段字节长度:
-- 语法
ALTER TABLE 表名 ALTER COLUMN 字段名 TYPE varchar(新字节长度);
-- 示例:将字段扩容至50字节
ALTER TABLE table_name ALTER COLUMN col_name TYPE varchar(50);附:快速定位超长字段 SQL
查询库内所有按字节限制的varchar字段,精准定位问题:
SELECT table_name,column_name,character_octet_length FROM information_schema.columns WHERE table_schema='public' AND data_type='character varying';
三、临时应急方案(程序侧)
数据库不便改动时,处理应用数据:
精简、截断超长文本,保证字节数 ≤ 字段定义长度;
检查初始化 / 批量导入文件(如你场景中的 XML 种子数据),修正超长内容。
四、验证配置是否生效(标准测试)
-- 建测试表
CREATE TABLE t_test(name varchar(4));
-- 插入4个中文(按字符校验,正常执行)
INSERT INTO t_test VALUES('测试中文');
-- 查询
SELECT * FROM t_test;
-- 用完可清理
DROP TABLE t_test;能正常插入则代表配置成功。
五、关键注意事项
参数
nls_length_semantics仅支持byte/char两个值;ALTER SYSTEM需超级管理员权限(sysdba);参数重载
pg_reload_conf()在线生效,无需重启服务;切换规则后,新旧数据无需迁移,仅改变长度校验逻辑;
该配置完成后,瀚高
varchar行为完全兼容 PostgreSQL,适配 Npgsql、PG 驱动无异常。
