oracle 讨论char varchar varchar2 数据类型选用

本文详细对比了Oracle数据库中char、varchar及varchar2三种字符串类型的特性与应用场景,探讨了它们之间的区别,特别是在空间效率与数据兼容性方面的考量。

http://www.javaeye.com/topic/133972

 

这3种字符串数据类型是我们使用最多的,我们在数据库设计时到底该怎么使用了?
 
首先我们先来分析3个数据类型的说明:
   1。char
         CHAR的长度是固定的,最长2000个字符。
 
    2。varchar 和 varchar2
         可以肯定的是oracle中目前是可以使用varchar数据类型的,但他们的区别我查了不少资料也没有找到一个准确的答案         最常见的说话是说 oracle中的varchar只是 varchar2的别名也就是同义词。
         其次也有人认为varchar是最大长度为2000的可变字符串(和sql server中的varchar一致),而 varchar2最大长度为4000。
 
知道了他们的特点我们就来讨论下使用区别
    1.char和varchar、varchar2
         由于varchar和varchar2用途类似,我们先来讨论char和他们的使用区别:
    varchar和 varchar2比char节省空间,在效率上比char会稍微差一些,即要想获得效率,就必须牺牲一定的空间,这也就是我们在数据库设计上常说的‘以空间换效率’。

  varchar和varchar2虽然比char节省空间,但是如果一个varchar和varchar2列经常被修改,而且每次被修改的数据的长度不同,这会引起‘行迁移’(Row Migration)现象,而这造成多余的I/O,是数据库设计和调整中要尽力避免的,在这种情况下用char代替varchar和varchar2会更好一些。

    当然还有一种情况就是象身份证这种长度几乎不变的字段可以考虑使用char,以获得更高的效率。

 

   2。varchar和varchar2

    这里就进入重点了,前面的区别我们在sql server中我们已经基本了解了,大家可能都知道,最多也就是复习下,但oracle增加了一个varchar2类型,是大家以前所没有用到过的。

     因为oracle保证在任何版本中该数据类型向上和向下兼容,但不保证varchar,还有其他数据中一般都有varchar这个数据类型。

     所以我得出了以下结论:

     如果想在oracle新版本的数据库兼容就不要用varchar,如果想和oracle之外其他数据库兼容就不要用varchar2

 

<think> 我们参考了用户提供的引用内容,特别是引用[1]中提到了to_char函数用于将数字转换为字符串,但用户的问题是关于CHAR类型转换为VARCHAR2类型。 另外,引用[3]中提到了CHARVARCHAR2在定义上的区别,但没有直接给出转换方法。 实际上,在Oracle中,CHARVARCHAR2都是字符类型,它们之间可以直接转换,但需要注意CHAR类型是固定长度,而VARCHAR2是可变长度。 转换方法: 1. 在查询中直接使用表达式转换:使用CAST函数或直接赋值(因为Oracle会自动进行字符类型转换,但需要注意空格填充问题)。 2. 使用TO_CHAR函数(虽然主要用于数字或日期转字符串,但也可以用于字符类型之间的转换,不过这里不是必须的)。 3. 注意:CHAR类型在存储时如果长度不足,会用空格填充到指定长度,而VARCHAR2不会。因此,在转换时可能需要去掉多余的空格。 具体方法: 方法一:使用CAST函数 SELECT CAST(char_column AS VARCHAR2(10)) FROM table; 方法二:直接赋值(在PL/SQL或查询中) SELECT TRIM(char_column) FROM table; -- 先去掉空格,然后自动转为VARCHAR2 或者直接:SELECT char_column FROM table; -- 在需要VARCHAR2的地方,Oracle会自动将CHAR转换为VARCHAR2(但会保留空格,所以通常需要TRIM) 但是,如果直接转换,CHAR类型的值后面可能会有空格,所以为了得到和VARCHAR2完全一致的值(即去掉尾部空格),我们通常使用RTRIM或TRIM。 另外,在表结构设计时,如果要将CHAR类型的列改为VARCHAR2类型,可以使用ALTER TABLE语句修改列的数据类型(但要注意数据长度和是否允许为空等约束)。 修改表结构的SQL: ALTER TABLE table_name MODIFY (column_name VARCHAR2(new_size)); 注意:在修改列类型时,如果表中已有数据,需要确保转换是可行的(通常CHARVARCHAR2没有问题,因为VARCHAR2的存储方式更节省空间,但要注意长度,VARCHAR2的最大长度要设置得足够大,至少不能小于原CHAR列中实际数据的最大长度)。 所以,根据用户需求,总结如下: 1. 在查询中转换,可以使用CAST或者TRIM函数。 2. 修改表结构,使用ALTER TABLE语句。 下面我们给出具体示例。 示例1:在查询中转换 假设有一张表t1,其中有一列c1是CHAR(10)类型,我们想查询为VARCHAR2类型(去掉尾部空格): SELECT RTRIM(c1) AS c1_varchar2 FROM t1; 或者 SELECT CAST(c1 AS VARCHAR2(10)) AS c1_varchar2 FROM t1; -- 注意:这样转换后,尾部空格依然存在,所以通常结合TRIM使用 实际上,CAST(c1 AS VARCHAR2(10)) 会保留尾部空格,所以如果要去掉空格,可以: SELECT TRIM(CAST(c1 AS VARCHAR2(10))) FROM t1; 但更简单的是:SELECT TRIM(c1) FROM t1; -- 这样得到的就是VARCHAR2类型(去掉尾部空格) 示例2:修改表结构 将表t1的列c1从CHAR(10)修改为VARCHAR2(10): ALTER TABLE t1 MODIFY (c1 VARCHAR2(10)); 注意:修改表结构时,如果该列有数据,并且数据长度超过VARCHAR2定义的长度,会报错。所以确保VARCHAR2的长度足够。 另外,在Oracle中,VARCHAR2的最大长度是4000字节(在12c以上版本,如果开启扩展数据类型,可以更大)。 因此,针对用户的问题,我们给出两种场景的解决方案:查询时转换和修改表结构。 由于用户没有明确是哪种场景,我们两种都提供。 最后,根据引用[2]中提到的,VARCHAR2是可变长度,不会用空格填充,所以在转换后可以节省空间,并且避免空格带来的比较问题。 </think>在Oracle中将CHAR类型转换为VARCHAR2类型有两种主要方法,具体选择取决于实际需求: ### 方法1:使用CAST函数(推荐) ```sql SELECT CAST(char_column AS VARCHAR2(50)) AS varchar_column FROM your_table; ``` **说明**: - 直接使用CAST函数显式转换数据类型 - `VARCHAR2(50)`中的长度需根据实际数据设定(参考原CHAR列定义) - 转换后会**保留尾部空格**,因为CHAR类型是固定长度(例如`'ABC '`会保持原样)[^2][^3] ### 方法2:使用RTRIM函数(去除尾部空格) ```sql SELECT RTRIM(char_column) AS varchar_column FROM your_table; ``` **说明**: - `RTRIM()`会移除CHAR类型自动填充的尾部空格 - 转换结果为`VARCHAR2`类型(长度自适应) - 适用于需要精确字符串比较的场景(例如`'ABC'`和`'ABC '`将被视为相同)[^1][^2] --- ### 重要注意事项 1. **数据截断风险** 若原CHAR列包含超过目标VARCHAR2长度的数据,转换会导致截断: ```sql -- 安全做法:先验证最大长度 SELECT MAX(LENGTH(char_column)) FROM your_table; ``` 2. **表结构修改(DDL)** 永久性转换列类型需使用`ALTER TABLE`: ```sql ALTER TABLE your_table MODIFY (char_column VARCHAR2(50)); ``` **注意**: - 需要表级锁,建议在低峰期操作 - 必须确保新长度≥现有数据最大长度[^1][^3] 3. **隐式转换规则** 在SQL语句中混合使用CHARVARCHAR2时: ```sql SELECT * FROM table1 t1 JOIN table2 t2 ON t1.char_col = t2.varchar2_col; -- Oracle自动转换CHARVARCHAR2 ``` 但显式转换可避免隐式转换的性能开销[^2][^4] 4. **存储差异** | 类型 | 存储方式 | 示例数据 `'ABC'` | |------------|-------------------|------------------| | **CHAR(10)** | 固定长度+空格填充 | `'ABC '` | | **VARCHAR2** | 变长(无填充) | `'ABC'` | 转换后存储空间通常减少30%-50%[^2] --- ### 应用场景建议 - 需要**精确字符串匹配** → 用`RTRIM()`去除空格 - 需**保留原始格式** → 用`CAST()` - **高频查询字段** → 优先转VARCHAR2提升性能 - **数据迁移/集成** → 统一为VARCHAR2减少类型冲突[^3][^5]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷月宫主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值