尽管已经有几个答案正确描述了 的行为char
,但我认为需要说的是,除了三种特定情况外,您不应该使用它:
- 您正在构建一个固定长度的文件或报告,并为 a 分配一个非空值
char
避免了编写rpad()
表达式的需要。例如,如果firstname
和lastname
都定义为char(20)
,则创建firstname || lastname
的更短的写法。rpad(firstname,20) || rpad(lastname,20)
Chuck Norris
- 您需要区分显式空字符串
''
和null
. 通常它们在 Oracle 中是一样的,但是分配''
给一个char
值会触发它的空白填充行为,而null
不会,所以如果区分差异很重要,而且我真的想不出为什么会这样,那么你有办法做到这一点。
- 您的代码是从某些其他系统移植(或需要兼容)由于遗留原因需要空白填充的。在那种情况下,你会坚持下去,我很同情你。
确实没有理由char
仅仅因为某些长度是固定的(例如Y/N
标志或 ISO 货币代码,例如'USD'
)而使用。它不是更有效,它不节省空间(没有神话般的 a 长度指示符varchar2
,只有一个空白填充开销char
),并且它不会阻止任何人输入较短的值。(如果您'ZZ'
在您的char(3)
货币列中输入,它只会被存储为'ZZ '
。)它甚至无法与曾经依赖它的某些古老版本的 Oracle 向后兼容,因为从来没有。
并且传染可以传播,因为(遵循最佳实践)您可以使用类似sales.currency%type
. 现在您的l_sale_currency
变量是一个隐形变量char
,对于较短的值(或 ),它会以不可见的空白填充,从而为隐藏不相等''
的错误打开了大门,即使您将它们都分配给了它们。l_sale_currency
l_refund_currency
'ZZ'
有人争辩说char(n)
(其中n是某个字符长度)表明值应该是n 个字符长,这是一种自我记录的形式。但是,如果您认真对待 3 字符格式(例如ISO-Alpha-3国家代码而不是ISO-Alpha-2),您肯定不会定义一个约束来执行规则,而不是让开发人员看一眼一个char(3)
数据类型并得出自己的结论?
CHAR
在 Oracle 6 中引入,我敢肯定,ANSI 兼容性的原因。可能有潜在客户决定购买哪种数据库产品,并且ANSI 兼容性在他们的清单上(或过去曾经是),并且CHAR
在 ANSI 标准中定义了空白填充,因此 Oracle 需要提供它。你不应该实际使用它。