Redshift从表A插入数据到表B报Invalid ASCII char: ef错误如何处理
报错根因
- 错误码8001提示的
Invalid ASCII char: ef对应的是UTF-8字节序标记(BOM)的首字节,属于隐藏非ASCII字符,常规文本查看工具不会显示,因此之前排查会误以为表A没有违规字符。 - 你提到的CHAR和VARCHAR转换逻辑确实会触发该错误:Redshift对固定长度CHAR类型的字符串校验规则远严于VARCHAR,要求所有字符必须是ASCII范围内的,而VARCHAR支持存储UTF-8字符,之前尝试强转为CHAR反而会触发更严格的校验规则,自然解决不了问题。
- 同版本集群表现不同的核心原因是两个集群的参数配置存在差异:可对比两个集群的
sql_parse_options参数配置,其中正常执行的集群大概率关闭了CHAR类型的严格ASCII校验规则。
解决方案
方案1(优先推荐,根治问题)
统一将两张表的对应字段修改为VARCHAR类型:
- 你存储的是数值类商品编码,本身不需要CHAR类型的固定长度空格填充逻辑,改用VARCHAR可以节省存储空间,同时规避CHAR类型的严格ASCII校验限制
- 该方案不需要对插入逻辑做额外修改,后续也不会再触发同类字符校验错误
方案2(临时兼容,不修改表结构)
如果业务侧强制要求保留CHAR类型字段,可在插入时对字段做清洗,过滤掉隐藏非ASCII字符:
- 先定位存在违规字符的行:
SELECT 商品编码字段 FROM 表A WHERE 商品编码字段 ~ '[^\x00-\x7F]';
- 插入时通过正则清洗非ASCII字符:
INSERT INTO 表B (商品编码字段, 其他字段) SELECT REGEXP_REPLACE(商品编码字段, '[^\x00-\x7F]', ''), 其他字段 FROM 表A;
如果确认是BOM头导致的问题,也可以针对性裁剪:
SELECT TRIM('\xef\xbb\xbf' FROM 商品编码字段) FROM 表A;
内容的提问来源于stack exchange,提问作者Sachiko
相关产品推荐
相关产品推荐

