瀚高数据库 22001 字符串超长错误

来源:本站原创 点击数: 发布时间:2026年06月24日

错误原文:22001: value too long for type character varying(xx byte) 

报错原因:varchar 字段在瀚高数据库中是按字节校验,中文 / 全角字符占用字节多,内容超出字段字节上限。


一、核心原理

  1. 瀚高默认 nls_length_semantics = bytevarchar(n) 按字节限制

    • 英文字符:1 字节 / 个

    • UTF8 中文:3 字节 / 个

    • 例:varchar(12) 最多存 4 个中文

  2. 标准 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';

三、临时应急方案(程序侧)

数据库不便改动时,处理应用数据:

  1. 精简、截断超长文本,保证字节数 ≤ 字段定义长度;

  2. 检查初始化 / 批量导入文件(如你场景中的 XML 种子数据),修正超长内容。


四、验证配置是否生效(标准测试)

-- 建测试表
CREATE TABLE t_test(name varchar(4));
-- 插入4个中文(按字符校验,正常执行)
INSERT INTO t_test VALUES('测试中文');
-- 查询
SELECT * FROM t_test;

-- 用完可清理
DROP TABLE t_test;

能正常插入则代表配置成功。


五、关键注意事项

  1. 参数 nls_length_semantics 仅支持 byte / char 两个值;

  2. ALTER SYSTEM 需超级管理员权限(sysdba);

  3. 参数重载 pg_reload_conf() 在线生效,无需重启服务;

  4. 切换规则后,新旧数据无需迁移,仅改变长度校验逻辑;

  5. 该配置完成后,瀚高 varchar 行为完全兼容 PostgreSQL,适配 Npgsql、PG 驱动无异常。