ERP物料编码乱码问题排查与解决方案
1. 问题背景:ERP物料档案为何会乱?
去年夏天,我接手了一个ERP系统物料档案混乱的紧急修复项目。采购部同事反映,他们连续三个月无法正常下单,系统总是提示"物料不存在"或"编码错误"。最诡异的是——在ERP界面明明能看到这个物料,但就是无法通过搜索找到,也无法在下单时选择。
经过初步排查,我们发现问题的核心在于物料编码中混入了不可见字符。这些字符在界面上完全不显示,但在系统底层却真实存在,导致所有基于编码的查询、匹配操作全部失效。采购部每次都要手动复制粘贴编码才能完成操作,效率直线下降。
提示:ERP系统中的物料编码就像身份证号,必须是唯一且纯净的字符串。任何不可见字符的混入都会导致系统识别异常。
2. 不可见字符的检测与定位
2.1 肉眼不可见的"幽灵字符"
我们首先用了一个简单的方法验证问题:将物料编码复制到记事本中。正常情况下,纯数字或字母组合在记事本中应该完全一致。但我们发现某些编码在记事本中会显示为方框或空白,这就是典型的不可见字符特征。
通过Hex编辑器进一步分析,发现这些编码中混入了以下特殊字符:
- 零宽度空格(Unicode U+200B)
- 软连字符(Unicode U+00AD)
- 字节顺序标记(BOM,U+FEFF)
2.2 问题根源追溯
经过代码审查,我们发现问题的产生有两个关键路径:
- 外部系统对接时,FastJSON序列化未正确处理转义字符
- 物料导入功能中,C#读取Excel文件时未过滤&等特殊符号
特别是当采购员从1688等平台复制物料信息时,平台自带的富文本格式会携带这些隐形字符。而我们的ERP系统接口没有做严格的输入过滤。
3. 解决方案设计与实施
3.1 临时应急方案
我们先用SQL脚本对现有数据库进行清理:
UPDATE material SET code = REPLACE( REPLACE( REPLACE(code, CHAR(0x200B), ''), CHAR(0x00AD), ''), CHAR(0xFEFF), '') WHERE code LIKE '%' + CHAR(0x200B) + '%' OR code LIKE '%' + CHAR(0x00AD) + '%' OR code LIKE '%' + CHAR(0xFEFF) + '%'同时为采购部提供了临时检查工具:
def has_invisible_chars(text): return any(ord(c) in (0x200B, 0x00AD, 0xFEFF) for c in text)3.2 永久修复方案
我们在三个层面建立了防护网:
前端防护:
- 所有物料编码输入框增加正则校验
/^[\w\-]+$/.test(code) // 只允许字母、数字、下划线和连字符后端防护:
- 在Spring拦截器中添加字符过滤
String sanitized = code.replaceAll("[\\u200B\\u00AD\\uFEFF]", "");数据库防护:
- 创建触发器检查新增/修改的记录
CREATE TRIGGER check_material_code BEFORE INSERT OR UPDATE ON material FOR EACH ROW BEGIN IF NEW.code REGEXP '[[:cntrl:]]' THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid character in material code'; END IF; END;
4. 经验总结与避坑指南
4.1 血泪教训
不要相信界面显示:我们最初浪费了两周时间,因为所有检查都在ERP界面进行,而界面自动过滤了这些字符。直到导出原始数据才发现问题。
系统对接要加白名单:与1688等平台对接时,应该只允许明确需要的字符通过,而不是试图过滤所有非法字符。
日志要记录原始数据:我们的审计日志存储的是处理后的数据,导致无法追溯问题源头。
4.2 推荐工具链
检测工具:
- Notepad++:显示所有字符(View → Show Symbol → Show All Characters)
- Hex Editor Neo:直接查看二进制编码
开发辅助:
// C#中检测不可见字符的方法 bool ContainsInvisibleChars(string input) { return input.Any(c => char.IsControl(c) && !char.IsWhiteSpace(c)); }监控方案:
- 在ELK日志系统中添加告警规则,当出现异常字符时触发通知
这次事故给我们的最大启示是:ERP系统的数据纯洁性就像饮用水安全,必须建立从源头到终端的全流程防护。一个肉眼看不见的字符,足以让整个采购体系瘫痪三个月。现在我们在所有关键字段上都实施了"三重过滤"机制,确保类似问题永远不会再现。