查看: 2570|回复: 10

【讨论】一个奇怪的字段长度的现象

[复制链接]
论坛徽章:
1
优秀写手
日期:2014-11-28 06:00:14
发表于 2014-11-27 15:58 | 显示全部楼层 |阅读模式
SQL> drop table yddh;

Table dropped.

SQL> create table yddh (yddh varchar2(12));  // 字段 yddh 长度为12

Table created.

SQL> insert into yddh select yddh from yddh_tmp;    // 报错,说YDDH的最大长度为12,插入时实际长度为20
insert into yddh select yddh from yddh_tmp
                        *
ERROR at line 1:
ORA-12899: value too large for column "CJCL"."YDDH"."YDDH" (actual: 20,
maximum: 12)


SQL> select length(yddh) from yddh_tmp  where  length(yddh)>12;  // 但是,大于12长度的字段却没有

no rows selected

SQL> insert into yddh select substr(yddh,1,9) from yddh_tmp;   // 截取前9位,但在插入表中,长度却算成了18,所以无法插入
insert into yddh select substr(yddh,1,9) from yddh_tmp
                        *
ERROR at line 1:
ORA-12899: value too large for column "CJCL"."YDDH"."YDDH" (actual: 18,
maximum: 12)


SQL> insert into yddh select substr(yddh,1,8) from yddh_tmp;   // 截取8位,插入时却算成16位
insert into yddh select substr(yddh,1,8) from yddh_tmp
                        *
ERROR at line 1:
ORA-12899: value too large for column "CJCL"."YDDH"."YDDH" (actual: 16,
maximum: 12)

yddh_tmp表的YDDH字段存放的是VARCHAR2 类型的手机号码,最大长度为11,但就是无法插入到表YDDH中,对YDDH表的YDDH字段而言,yddh_tmp表的YDDH字段里,一个字符为何算成了两个长度,但在用length函数算时却是1个长度,高人求解啊!!!

SQL>
我以为YDDH的字段是全角的于是用TO_SINGLE_BYTE(YDDH)转换后再插入还是不行,我如何才能插入?


论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
发表于 2014-11-27 16:10 | 显示全部楼层
dump下看看,varchar2(12)是12个byte,不是长度是12,lengthb才是真实的

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-11-28 06:00:14
 楼主| 发表于 2014-11-27 16:51 | 显示全部楼层
dingjun123 发表于 2014-11-27 16:10
dump下看看,varchar2(12)是12个byte,不是长度是12,lengthb才是真实的

dump 里面显示的是这个
select dump(A.yddh) from yddh_tmp A where rownum <10
Typ=1 Len=11: 49,51,51,49,57,48,57,54,54,54,56
Typ=1 Len=11: 49,56,57,57,57,53,57,53,55,49,57
Typ=1 Len=11: 49,51,48,57,53,48,53,51,51,52,52
Typ=1 Len=11: 49,53,48,48,57,48,55,49,55,56,57
Typ=1 Len=11: 49,51,49,55,57,56,56,56,53,55,54
Typ=1 Len=11: 49,53,53,57,57,57,57,48,54,53,55
Typ=1 Len=11: 49,51,48,57,53,49,53,52,51,52,57
Typ=1 Len=11: 49,51,51,54,57,48,55,56,56,56,56
Typ=1 Len=11: 49,51,56,57,57,50,53,48,51,51,51

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
发表于 2014-11-27 16:55 | 显示全部楼层
前10行没有问题,len=11代表lengthb=11,11个byte

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
发表于 2014-11-27 16:55 | 显示全部楼层
你desc yddh_tmp试试

使用道具 举报

回复
论坛徽章:
401
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2014-11-27 16:56 | 显示全部楼层
如果是中文字符集gbk,经常会乘以2的

使用道具 举报

回复
论坛徽章:
401
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2014-11-27 16:58 | 显示全部楼层
substrb试试

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-11-28 06:00:14
 楼主| 发表于 2014-11-27 17:04 | 显示全部楼层
dingjun123 发表于 2014-11-27 16:10
dump下看看,varchar2(12)是12个byte,不是长度是12,lengthb才是真实的

找出来了兔子,存放手机号的字段里存放了10个汉字,这10个汉字用length测试长度为10,可YDDH表却认其长度为20。

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
发表于 2014-11-27 17:09 | 显示全部楼层
-Bill 发表于 2014-11-27 17:04
找出来了兔子,存放手机号的字段里存放了10个汉字,这10个汉字用length测试长度为10,可YDDH表却认其长度 ...

所以嘛,我说的是前10行没有问题。。。后面的就说不准了,也就是yddh两个表定义长度要一致,那就没有问题了

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-11-28 06:00:14
 楼主| 发表于 2014-11-27 17:11 | 显示全部楼层
〇〇 发表于 2014-11-27 16:58
substrb试试

对于汉字来说,用length算时一个汉字算1个长度,若用varchar2类型字段来存,则一个汉字占用的是两个长度,所以一个字段若定义为 varchar2(10),则最多存放5个汉字,但用length测试其为结果为5

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表