Oracle中的varchar和varchar2有啥区别?
Posted
技术标签:
【中文标题】Oracle中的varchar和varchar2有啥区别?【英文标题】:What is the difference between varchar and varchar2 in Oracle?Oracle中的varchar和varchar2有什么区别? 【发布时间】:2010-11-13 08:38:27 【问题描述】:varchar 和 varchar2 有什么区别?
【问题讨论】:
这个问题受到这篇博文启发的可能性有多大? joelonsoftware.com/articles/GuerrillaInterviewing3.html 【参考方案1】:目前 VARCHAR 的行为与 VARCHAR2 完全相同。但是,不应使用 VARCHAR
类型,因为它是为将来使用而保留的。
取自:Difference Between CHAR, VARCHAR, VARCHAR2
【讨论】:
@PhilipRegoVARCHAR
不应使用。我编辑了它【参考方案2】:
目前,它们是相同的。但以前
-
在网上某处,我读到了,
VARCHAR
由 Oracle 保留,以支持将来区分 NULL
和空字符串,正如 ANSI 标准规定的那样。
VARCHAR2
不区分 NULL
和空字符串,而且永远不会。
-
还有,
Emp_name varchar(10)
- 如果输入的值小于 10 位,则无法删除剩余空间。它总共使用了 10 个空格。
Emp_name varchar2(10)
- 如果您输入的值小于 10 位,则剩余空间会自动删除
【讨论】:
我最近偶然发现了这篇文章,请注意它是不正确的。执行以下命令,两个字段都是 3 个字符:create table deleteme_table(v varchar(10), v2 varchar2(10)); insert into deleteme_table (v, v2) values ('abc','abc'); select v, length(v), v2, length(v2) from deleteme_table;
@BrianLeach:是的,它们目前的行为相同,但 Oracle 将在未来改变一些东西,使其行为符合标准规定的行为。【参考方案3】:
经过一些实验(见下文),我可以确认,截至 2017 年 9 月,the accepted answer:-
中描述的功能没有任何变化-
Rextester demo for Oracle 11g:
对于
VARCHAR
,空字符串插入为NULL
s
和VARCHAR2
。
LiveSQL demo for Oracle 12c: 结果相同。
an answer to a different question 很好地解释了这两个关键字的历史原因。
【讨论】:
【参考方案4】:取自最新稳定的 Oracle 生产版本 12.2: Data Types
主要区别在于VARCHAR2
是内部数据类型,VARCHAR
是外部数据类型。所以我们需要了解内部和外部数据类型之间的区别......
在数据库中,值存储在表的列中。在内部,Oracle 以称为内部数据类型的特定格式表示数据。
通常,OCI(Oracle 调用接口)应用程序不使用数据的内部数据类型表示,而是使用由编写它们的语言预定义的宿主语言数据类型。当数据在 OCI 客户端应用程序和数据库表之间传输时,OCI 库会在内部数据类型和外部数据类型之间转换数据。
外部类型通过使用宿主语言类型而不是专有数据格式为程序员提供了便利。在 Oracle 数据库和 OCI 应用程序之间传输数据时,OCI 可以执行广泛的数据类型转换。 OCI 外部数据类型比 Oracle 内部数据类型多。
VARCHAR2
数据类型是可变长度的字符串,最大长度为 4000 字节。如果 init.ora 参数 max_string_size 为默认值,则VARCHAR2
的最大长度可以为 4000 字节。如果init.ora参数max_string_size=extended,则VARCHAR2
的最大长度可以是32767字节
VARCHAR
数据类型存储不同长度的字符串。前 2 个字节包含字符串的长度,其余字节包含字符串。绑定或定义调用中字符串的指定长度必须包含两个长度字节,因此可以接收或发送的最大VARCHAR
字符串长度为65533字节,而不是65535。
在 12.2 数据库中的快速测试表明,作为 内部数据类型,Oracle 仍将 VARCHAR
视为 VARCHAR2
的 伪类型。它不是 SYNONYM
,它是 Oracle 中的实际对象类型。
SQL> select substr(banner,1,80) from v$version where rownum=1;
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> create table test (my_char varchar(20));
Table created.
SQL> desc test
Name Null? Type
MY_CHAR VARCHAR2(20)
VARCHAR
还对 ProC/C++ 预编译器选项有一些影响。有兴趣的程序员,链接在:Pro*C/C++ Programmer's Guide
【讨论】:
那么这是否意味着VARCHAR
仍然对待'' == null
?
是的。上面关于内部与外部类型的讨论来自 OCI 参考。 12.2 SQL Language Reference 仍然带有与 VARCHAR 相同的“请勿使用”语句。
这就是我讨论 OCI 差异的原因,否则它几乎是为将来使用而保留的,或者正如他们所说的“可变长度”,这可能暗示着诸如多字节 UTF8 之类的字符集...
您展示了声明为 VARCHAR 的值作为 VARCHAR2 存储在数据库中,但是 VARCHAR 的最大长度(65533 字节)大于 VARCHAR2 的最大长度(32767 字节)。数据库如何处理?
IIRC,很久以前(也许是 Oracle 6?)有一个 VARCHAR 类型对空格填充行为不端 - 还是截断空格? AAR,VARCHAR2 就是答案。 Oracle 一直在说他们会带回 VARCHAR,但我敢肯定,当空字符串不为空时,他们会咬牙切齿。【参考方案5】:
VARCHAR 最多可存储 2000 个字节的字符,而 VARCHAR2 最多可存储 4000 个字节的字符。
如果我们将数据类型声明为 VARCHAR,那么它将占用 NULL 值的空间。在 VARCHAR2 数据类型的情况下,它不会为 NULL 值占用任何空间。例如,
name varchar(10)
即使名字是 'Ravi__' 也会保留 6 字节的内存,而
name varchar2(10)
会根据输入字符串的长度预留空间。例如,“Ravi__”的 4 字节内存。
这里,_代表NULL。
注意:varchar 将为空值保留空间,而 varchar2 不会为空值保留任何空间。
【讨论】:
我认为这个答案混淆了VARCHAR
和CHAR
。【参考方案6】:
就目前而言,它们是同义词。
VARCHAR
由Oracle
保留,以支持将来区分NULL
和空字符串,正如ANSI
标准规定的那样。
VARCHAR2
不区分 NULL
和空字符串,而且永远不会。
如果你依赖空字符串和NULL
是同一个东西,你应该使用VARCHAR2
。
【讨论】:
以前没听说过这个理由,这很有用。谢谢。作为记录,Oracle 中的主要字符类型是“varchar2”仍然是完全可笑的。这不会让其他人觉得这是一个可怕的杂物吗?似乎我在学习编程的第一周就解决了一些问题。 @Ian: 主要类型是VARCHAR2
,因为目前没有像VARCHAR
那样行为的类型。事实上,在正确实施之前,您根本不应该使用VARCHAR
。
谢谢,@Quassnoi。所以我想愚蠢的部分是Oracle没有像其他所有数据库一样的适当的VARCHAR,那么呢?这里发生了一些愚蠢的事情,我敢肯定...... :)
@Ian:在开发 Oracle 的时候,还没有标准。到标准出现时,它已经背负了遗留应用程序的负担。我们都知道它是如何发生的。
抱歉,incorrect comment I was responding to 的作者其实是@UnKnown。 where x is NULL
从where x = ''
返回不同结果的事实确实不意味着NULL
和''
在任何方面都不同。不同的行为是由于 =
运算符。以上是关于Oracle中的varchar和varchar2有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
如何将oracle表中的字段由integer 转变为varchar2(50)
新手小白,在oracle中varchar2类型,能设置最大值吗