oracle慎用char数据类型
2010-12-01 16:50
330 查看
昨天遇到了一个很奇怪的问题。一个很简单的功能,选择学习中心,然后选择课程,如果表中存在这个课程,就删除后重新添加(当然要是我写不会这么写的),主要是调用一个储存过程,如下
代码
1 ALTER TABLE OEMS.LCENTER_INPUTGRADEPOWER ADD (
2 CONSTRAINT LCINPUTGRADEPO_R_UPBUILDCOU_ID
3 FOREIGN KEY (UPBUILDCOURSEID)
4 REFERENCES OEMS.JW_UPBUILDCOURSE (UPBUILDCOURSEID),
5 CONSTRAINT LCINPUTGRADEPOWER_R_LC_CODE
6 FOREIGN KEY (LCENTERCODE)
7 REFERENCES OEMS.JC_LCENTER (LCENTERCODE));
这里用到了两个约束 ,一个是OEMS.JW_UPBUILDCOURSE 表的UPBUILDCOURSEID
一个是OEMS.JC_LCENTER的LCENTERCODE ,我单独查询这两个表'C052701'和65279都有值。这就很奇怪了,既然报错是约束,那肯定是插入的值和外键表中的值匹配不上啊。
尝试一:我试着单独向LCenter_InputGradePower 表插入数据,成功!
尝试二:调用存储过程执行,错误
看来问题还是在存储过程上,仔细查看存储过程,发现表jc_lcenter和UPBUILDCOURSEID字段的数据类型都是varchar2(8),但是存储过程内部采用的内部变量确实一个
v_firstword char(8);
忽然想到传入的学习中心的编码是7位的C052701 这样在采用char数据类型存储的时候,不足8位的会补零的,但是对应的lcentercode的字段是varchar2(8)明显的
C0527010 与 C052701 是不同的。
原因找到了,那解决起来很简单。
把存储过程内部变量的v_firstword的数据类型更新为varchar2(8)就OK了。
验证通过。
教训:这个小小的问题从发现到解决花费了2-3个小时的时间,起先的排查点从程序---到发布---数据---最后才是数据库对象上,可谓是一个大圈。但是也给自己提了个醒,在oracle中尤其是存储过程和包中,尽量少用char类型,除非你很确定值不会变。但是这个也是很不保险的,因为这个问题当初的程序员可能得到的信息是学习中心的编码就是8位是不会变的,但是随着业务的发展,在目前就已经发生了变化,导致了问题。所以好的程序员一定要具有前瞻性,对可能出现问题的地方做到提前预防,提前处理。如果能预见到char数据类型可能带来的问题,那就能避免类似的问题发生。
代码
1 ALTER TABLE OEMS.LCENTER_INPUTGRADEPOWER ADD (
2 CONSTRAINT LCINPUTGRADEPO_R_UPBUILDCOU_ID
3 FOREIGN KEY (UPBUILDCOURSEID)
4 REFERENCES OEMS.JW_UPBUILDCOURSE (UPBUILDCOURSEID),
5 CONSTRAINT LCINPUTGRADEPOWER_R_LC_CODE
6 FOREIGN KEY (LCENTERCODE)
7 REFERENCES OEMS.JC_LCENTER (LCENTERCODE));
这里用到了两个约束 ,一个是OEMS.JW_UPBUILDCOURSE 表的UPBUILDCOURSEID
一个是OEMS.JC_LCENTER的LCENTERCODE ,我单独查询这两个表'C052701'和65279都有值。这就很奇怪了,既然报错是约束,那肯定是插入的值和外键表中的值匹配不上啊。
尝试一:我试着单独向LCenter_InputGradePower 表插入数据,成功!
尝试二:调用存储过程执行,错误
看来问题还是在存储过程上,仔细查看存储过程,发现表jc_lcenter和UPBUILDCOURSEID字段的数据类型都是varchar2(8),但是存储过程内部采用的内部变量确实一个
v_firstword char(8);
忽然想到传入的学习中心的编码是7位的C052701 这样在采用char数据类型存储的时候,不足8位的会补零的,但是对应的lcentercode的字段是varchar2(8)明显的
C0527010 与 C052701 是不同的。
原因找到了,那解决起来很简单。
把存储过程内部变量的v_firstword的数据类型更新为varchar2(8)就OK了。
验证通过。
教训:这个小小的问题从发现到解决花费了2-3个小时的时间,起先的排查点从程序---到发布---数据---最后才是数据库对象上,可谓是一个大圈。但是也给自己提了个醒,在oracle中尤其是存储过程和包中,尽量少用char类型,除非你很确定值不会变。但是这个也是很不保险的,因为这个问题当初的程序员可能得到的信息是学习中心的编码就是8位是不会变的,但是随着业务的发展,在目前就已经发生了变化,导致了问题。所以好的程序员一定要具有前瞻性,对可能出现问题的地方做到提前预防,提前处理。如果能预见到char数据类型可能带来的问题,那就能避免类似的问题发生。
相关文章推荐
- oracle中的数据类型char
- Oracle中对number类型数据to_char()出现各位少0,或者值为###的处理
- oracle中char和varchar2数据类型的区别
- oracle 数据库中讨论char ,varchar ,varchar2 数据类型!
- oracle中的数据类型char
- 1. Oracle内置数据类型--字符串, 2. char的大小和字符集有关
- Oracle的数据类型转换 to_char(date)
- Oracle中char数据类型,length长度不足时,会自动用空格补上
- oracle中char和varchar2数据类型的区别
- oracle 日期或数据转换为char数据类型
- 〖Oracle 转载〗Oracle的数据类型转换 to_char
- oracle数据类型之char&varchar
- Oracle的数据类型转换 to_char(date)
- 在Struts中慎用oracle char类型的字段
- Oracle中的数据类型转换函数to_char
- Oracle基本数据类型存储格式浅析(五)——RAW类型
- ORACLE定义长度的数据类型
- oracle的date类型数据 我是这么认为
- 关于SQL92标准和Sybase,SQLServer2000,Oracle的数据类型对比关系
- oracle VARRAY数据类型