2

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

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

varchar2使用这些 over 的数据类型有什么好处char吗?

使用 Oracle 11g 第 2 版。

4

3 回答 3

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 未存储为“这是一个字符串”;相反,它存储为“这是一个字符串”,因为 CHAR 变量在右侧用空格填充到变量声明中指定的大小。是的,我可以仔细计算字符串中的字符数(有 17 个,顺便说一句),然后仔细调整了声明,但这只是1970年代(我记得有些模糊的十年,不想重温:-)。而且,天哪,我算错了字符串中的字符数,不会奏效的。

我将使用 CHAR 而不是 VARCHAR2 的一种情况是,常量的变量只应该是单个字符长。IMO 将某些内容声明为 VARCHAR2(1) 是错误的。:-)

顺便说一句,我会注意到,如果您查看 SYS.STANDARD 包,您会发现 CHAR 被声明为

subtype CHAR is VARCHAR2;

因此,CHARVARCHAR2。不确定空间填充是如何完成的,但很可能空间填充是在运行时完成的,因此会增加额外的时间。

两者之间有性能优势吗?最多不会太多。我想如果一个 CHAR 变量有一些空格填充,那么比较一个相等的未填充的 VARCHAR2 值需要更长的时间,但实际上我认为这并不重要。此外,由于空间填充是在运行时完成的,这将增加时间。我怀疑这是一种清洗,肯定会被 SQL 影响淹没。

分享和享受。

于 2013-08-08T16:25:46.343 回答
1

CHAR 数据类型和 VARCHAR2 数据类型的存储方式相同......因此,在您描述的情况下,没有区别。

CHAR 和 VARCHAR 之间的区别在于 CHAR(n) 始终为 N 字节长,插入时将填充空白以确保这一点。另一方面,varchar2(n) 的长度为 1 到 N 个字节,不会填充空白。

于 2013-08-08T16:05:46.397 回答
-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,它是空白填充到最大长度的。

于 2013-08-08T15:55:36.097 回答