不知道全国有多少数据系统被 Oracle 数据库的 VARCHAR2(X) 的默认单位给坑了

11 小时 3 分钟前
 laminux29
当我们建表时,使用 VARCHAR2(50),从开发的角度,可能会认为是 VARCHAR2(50 个字符),而不是 VARCHAR2(50 字节)。

但 Oracle 数据库,如果你没写清楚 VARCHAR2(50 CHAR) 还是 VARCHAR2(50 BYTE),而只是写了 VARCHAR2(50),那么 Oracle 大概率默认行为是 VARCHAR2(50 BYTE)。

这几天帮助同事清理数据,发现系统中有丢失数据的问题,查了失败日志,才发现是这个问题。
不知道全国多少数据系统被 Oracle 的这个特性坑了。
404 次点击
所在节点    数据库
4 条回复
NotFoundEgg
10 小时 25 分钟前
这个也算 Oracle 的常识了,GBK 和 UTF8 还决定了 VARCHAR2(50) 能存多少个汉字

之前我这边有个库是 GBK 的,非要迁数据到 UTF8 的库,好多字段都要扩
laminux29
3 小时 35 分钟前
@NotFoundEgg 这是一家数据公司的拳头产品,出现了这个问题,有可能是产品设计师第一次遇到 Oracle 的这个坑,没测试、没做验证,就着急赶工地把产品做出来了。这家公司还是全国的数据行业的 TOP 3 公司,不知道他们这款产品,害了多少公司、单位与企业。

而且这个 BUG 最诡异的地方,是它并不是一定会明显地失败,无法让开发与甲方能很明显地发现。

BUG 触发的条件,只有当源表的 VARCHAR2(X CHAR)的字符串长度超过中间表 VARCJAR2(X BYTE)字段的 1/3 长度时,Oracle 才会报一个错误。而且,如果数据复制过程,不是批量的数据复制事务,而是一条一条的数据复制,那么丢失数据的告警,只会被淹没在成功的日志里。这时如果甲方的纪律性不强,没有去仔细看日志,那也很难发现这个问题。因为此时会有大量数据被成功复制,少数数据因这个 BUG 发生丢失问题。
chiikawa
2 小时 32 分钟前
那你还得再记多一个,Oracle 的 char 会填充空白字符到你设置的长度
czzt1
2 小时 26 分钟前
这种问题已经算常识了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1209513

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX