百科 / 错误代码 / Class 22 数据异常
22001 string_data_right_truncation
ERROR 已实测 详解 实测通过
- 条件名
string_data_right_truncation- 宏名称
ERRCODE_STRING_DATA_RIGHT_TRUNCATION- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
固定 varchar 路径报告 value too long for type character(%d);hstore、varbit 等路径会使用各自的具体变体。
共享案例创建 varchar_limits(value varchar(3)),用 'too-long' 触发 22001,再插入修复值 'ok' 并查询存储值。应在自动提交下逐条发送这些语句:触发语句预期失败,之后再执行修复语句。案例运行器在结束阶段负责清理对象。
CREATE TABLE varchar_limits (value varchar(3));
INSERT INTO varchar_limits VALUES ('too-long');
INSERT INTO varchar_limits VALUES ('ok');
SELECT value FROM varchar_limits;
校准实测 character varying(3) 拒绝超长值并报告 value too long for type character varying(3);修正值 ok 成功,运行器的两条自动提交会话均回到 IDLE。
报文
固定 character 和 varchar guard 以 ERROR 严重性报告 primary 模板 value too long for type character(%d) 与 value too long for type character varying(%d)。hstore 与 varbit 路径使用各自的 primary:string too long for hstore key、string too long for hstore value 和 bit string too long for type bit varying(%d)。这些源码组没有独立 DETAIL 或 HINT;本次运行只观察了上面的 varchar 模板。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
value too long for type character(%d)
value too long for type character varying(%d)
string too long for hstore key
string too long for hstore value
bit string too long for type bit varying(%d)
含义
当值无法满足字符串类型的长度契约时会出现 22001。PostgreSQL 按字符数而不是字节数计算 character(n) 和 character varying(n),因此 value too long for type character(%d) 中的 %d 指向响应里的 typmod。固定 varchar.c 是服务器端检查;hstore 键值和 bit string 有各自的路径和消息。
值进入类型的方式也会改变边界。varchar() 和 bpchar() 都接收 isExplicit 标志:赋值/输入转换遇到超出的非空格字符会报错,而显式 cast 到有界类型可以按 PostgreSQL 字符类型规则截断;超出的尾随空格和非空格字符处理不同。修改存储或校验前应先明确这个选择。
诊断
保存 schema_name、table_name、column_name、datatype_name、routine 和完整 message。先从目录确认目标类型和 typmod,再按字符数而不是字节数测量实际值。区分赋值/插入、显式 cast,以及 hstore/bit 路径,因为它们的截断行为并不完全相同。
常见 varchar 路径要检查超出宽度的后缀是否全是尾随空格。只有尾随空格超出时可能适用字符类型的截断规则;有意义的非空格数据应视为契约被拒绝。固定源码消息说明的是类型宽度问题,不是一般编码或网络错误。
处置
选择能保留数据契约的修复:校验并拒绝超长输入,有意扩大列/类型,或只在业务明确允许时显式 cast 截断。截断前保存原值和目标 typmod;静默裁剪标识符、键或审计文本可能写入与调用方意图不同的内容。本次固定案例使用自动提交,失败语句结束后会话仍为 IDLE;显式事务中应先回滚整个事务,或回滚到语句前建立的保存点,再重试修正值。修正输入或 schema 后重新转换,并核对保存后的字符长度。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
varchar_width_overflow PG 10 / 18 有 SQL
触发
Insert a value longer than the declared varchar(3) width.
断言
- SQLSTATE is 22001
- The varchar width diagnostic names character varying(3)
- The failed autocommit session remains IDLE
- A representable value is stored after the error
处置
Use a value that satisfies the declared width or revise the data contract explicitly; do not rely on an explicit cast that silently truncates the input.
清理
Drop the case schema with an owner connection.
版本
锁定目录从 7.4 记录该条件,并在列出的正式快照及 19beta3 中出现;固定源码覆盖为 PostgreSQL 18.6。
来源
- 上游源码 src/backend/utils/errcodes.txt 第 200 行
- 上游源码 src/backend/utils/adt/varchar.c 第 300–313 行
- 上游源码 contrib/hstore/hstore_io.c 第 407–434 行
- 上游源码 src/backend/utils/adt/varbit.c 第 733–758 行
- 上游源码 src/backend/utils/adt/varchar.c 第 633–640 行
- 核验材料 verify/cases/22001/snippets.json
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
22001 is string_data_right_truncation in SQLSTATE Class 22.
-
The character and character-varying input paths check the non-explicit value against the typmod and emit distinct primary templates; explicit casts may truncate according to the type rules.
-
hstore key/value and varbit length checks use 22001 with subsystem-specific messages.
-
The locked catalogue records 22001 from 7.4 without proving an exact implementation introduction date.
-
The varchar_width_overflow case passed on isolated PostgreSQL 18.6 and 10.21: the non-fitting varchar(3) value produced 22001, left the autocommit session IDLE, and the corrected value ok was accepted.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | varchar_width_overflow |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | varchar_width_overflow |
同类错误代码
Class 22 数据异常 下的其他成员。
22000data_exception22002null_value_no_indicator_parameter22003numeric_value_out_of_range22004null_value_not_allowed22005error_in_assignment22007invalid_datetime_format22008datetime_field_overflow22009invalid_time_zone_displacement_value2200Bescape_character_conflict2200Cinvalid_use_of_escape_character2200Dinvalid_escape_octet2200Fzero_length_character_string2200Gmost_specific_type_mismatch2200Hsequence_generator_limit_exceeded2200Lnot_an_xml_document2200Minvalid_xml_document2200Ninvalid_xml_content2200Sinvalid_xml_comment2200Tinvalid_xml_processing_instruction22010invalid_indicator_parameter_value22011substring_error22012division_by_zero22013invalid_preceding_or_following_size22014invalid_argument_for_ntile_function22015interval_field_overflow22016invalid_argument_for_nth_value_function22018invalid_character_value_for_cast22019invalid_escape_character2201Binvalid_regular_expression2201Einvalid_argument_for_logarithm2201Finvalid_argument_for_power_function2201Ginvalid_argument_for_width_bucket_function2201Winvalid_row_count_in_limit_clause2201Xinvalid_row_count_in_result_offset_clause22021character_not_in_repertoire22022indicator_overflow22023invalid_parameter_value22024unterminated_c_string22025invalid_escape_sequence22026string_data_length_mismatch22027trim_error2202Earray_subscript_error2202Ginvalid_tablesample_repeat2202Hinvalid_tablesample_argument22030duplicate_json_object_key_value22031invalid_argument_for_sql_json_datetime_function22032invalid_json_text22033invalid_sql_json_subscript22034more_than_one_sql_json_item22035no_sql_json_item22036non_numeric_sql_json_item22037non_unique_keys_in_a_json_object22038singleton_sql_json_item_required22039sql_json_array_not_found2203Asql_json_member_not_found2203Bsql_json_number_not_found2203Csql_json_object_not_found2203Dtoo_many_json_array_elements2203Etoo_many_json_object_members2203Fsql_json_scalar_required2203Gsql_json_item_cannot_be_cast_to_target_type22P01floating_point_exception22P02invalid_text_representation22P03invalid_binary_representation22P04bad_copy_file_format22P05untranslatable_character22P06nonstandard_use_of_escape_character