为什么使用varchar2而不是char作为包常量?

时间:2013-08-08 15:44:20

标签: oracle plsql

刚刚遇到一个包,它定义了大量的包全局常量字符串:

DESTINATION_1 CONSTANT VARCHAR2(13) := '515 Pine Lane';
DESTINATION_2 CONSTANT VARCHAR2(18) := '670 Woodhaven Lane';

使用varchar2作为char以上的数据类型有什么好处吗?

使用Oracle 11g第2版。

3 个答案:

答案 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。