刚刚遇到一个包,它定义了大量的包全局常量字符串,如下所示:
DESTINATION_1 CONSTANT VARCHAR2(13) := '515 Pine Lane';
DESTINATION_2 CONSTANT VARCHAR2(18) := '670 Woodhaven Lane';
varchar2
使用这些 over 的数据类型有什么好处char
吗?
使用 Oracle 11g 第 2 版。
一般来说,我对所有字符串变量或常量声明使用 VARCHAR2 而不是 CHAR,原因很简单,即 VARCHAR2 语义更符合我的期望。这里的问题是,如果开发人员对常量长度的计数不够准确,如果声明为 CHAR,它将在右侧用空格填充,而如果声明为 VARCHAR2,它将简单地存储而没有填充。考虑:
DECLARE
strFixed CHAR(20) := 'This is a string';
strVariable VARCHAR2(20) := 'This is a string';
BEGIN
IF strFixed = strVariable THEN
DBMS_OUTPUT.PUT_LINE('Equal');
ELSE
DBMS_OUTPUT.PUT_LINE('Not equal');
END IF;
END;
乍一看,您可能希望它打印“Equal”,但实际上它会打印“Not equal”。之所以如此,是因为 strFixed 未存储为“这是一个字符串”;相反,它存储为“这是一个字符串”,因为 CHAR 变量在右侧用空格填充到变量声明中指定的大小。是的,我可以仔细计算字符串中的字符数(有 17 个,顺便说一句),然后仔细调整了声明,但这只是1970年代(我记得有些模糊的十年,不想重温:-)。而且,天哪,我算错了字符串中的字符数,不会奏效的。
我将使用 CHAR 而不是 VARCHAR2 的一种情况是,常量的变量只应该是单个字符长。IMO 将某些内容声明为 VARCHAR2(1) 是错误的。:-)
顺便说一句,我会注意到,如果您查看 SYS.STANDARD 包,您会发现 CHAR 被声明为
subtype CHAR is VARCHAR2;
因此,CHAR是VARCHAR2。不确定空间填充是如何完成的,但很可能空间填充是在运行时完成的,因此会增加额外的时间。
两者之间有性能优势吗?最多不会太多。我想如果一个 CHAR 变量有一些空格填充,那么比较一个相等的未填充的 VARCHAR2 值需要更长的时间,但实际上我认为这并不重要。此外,由于空间填充是在运行时完成的,这将增加时间。我怀疑这是一种清洗,肯定会被 SQL 影响淹没。
分享和享受。
CHAR 数据类型和 VARCHAR2 数据类型的存储方式相同......因此,在您描述的情况下,没有区别。
CHAR 和 VARCHAR 之间的区别在于 CHAR(n) 始终为 N 字节长,插入时将填充空白以确保这一点。另一方面,varchar2(n) 的长度为 1 到 N 个字节,不会填充空白。
嗨,这可能是我的假设,但 varchar2 可能已用于性能,
char 只是填充到最大长度的 varchar2 空白。
create table t ( x varchar2(30), y char(30) );
insert into t (x,y) values ( rpad('a',' ',30), 'a' );
绝对没有,并且考虑到下面 X 和 Y 列之间的差异:
insert into t (x,y) values ('a','a')
是 X 消耗 3 个字节(空指示符,前导字节长度,'a' 1 个字节)和 Y 消耗 32 个字节(空指示符,前导字节长度,'a' 30 个字节)
嗯,varchar2 将在某种程度上“在性能方面具有优势”。char(30) 始终是 30 个字节,这对我们有帮助 - 对我们来说,它只是一个 varchar2,它是空白填充到最大长度的。