刚刚遇到一个包,它定义了大量的包全局常量字符串:
DESTINATION_1 CONSTANT VARCHAR2(13) := '515 Pine Lane';
DESTINATION_2 CONSTANT VARCHAR2(18) := '670 Woodhaven Lane';
使用varchar2
作为char
以上的数据类型有什么好处吗?
使用Oracle 11g第2版。
答案 0 :(得分:5)
通常我对所有字符串变量或常量声明使用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不存储为'This is a string';相反,它存储为“这是一个字符串”,因为CHAR变量在右边填充,空白为变量声明中指定的大小。是的,我可以仔细计算中的字符数字符串(顺便说一下有17个),然后小心地调整了声明,但那只是 SO 1970年代(十年我记得有些朦胧而且不在乎重访:-)。哦,亲爱的,我错误地计算了字符串中的字符数,因此固定的字符串将被填充在右边以填充到声明的长度,而我的比较仍然将不起作用。
我将使用CHAR而不是VARCHAR2的一种情况是,如果常量变量只应该是单个字符长。 IMO宣称VARCHAR2(1)是错误的。 : - )
刚才我会注意到,如果你查看SYS.STANDARD包,你会发现CHAR被声明为
subtype CHAR is VARCHAR2;
因此,CHAR 是VARCHAR2。不确定空间填充是如何完成的,但很可能是空间填充在运行时完成,因此增加了额外的时间。
对于其中一个是否有性能优势?最多不会太多。我想如果一个CHAR变量有一些空格填充,它将比一个等效的无填充VARCHAR2值更长一些头发,但实际上我认为这不重要。此外,由于空间填充在运行时完成,这将增加时间。我怀疑它是一种清洗,并且肯定会被SQL效应所淹没。
分享并享受。
答案 1 :(得分:1)
CHAR数据类型和VARCHAR2数据类型以相同的方式存储...因此,在您描述的情况下,没有区别。
CHAR和VARCHAR之间的区别在于CHAR(n)总是N字节长,插入时将填充空白以确保这一点。另一方面,varchar2(n)将是1到N个字节长,它不会被填空。
答案 2 :(得分:-1)
嗨,这可能是我的假设,但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。