一、背景
之前设计了一个学生选课模式的oracl数据表,由于是按照老师要求并且参考了视频,所以表中的主键字段全都设计的是varchar2(2)类型。这周末,老师布置了作业。要求用序列和触发器实现主键的自增长。下面就谈谈我在to_char()函数遇到的坑,关于序列和触发器我将在另一篇文章里进行说明。
二、补个知识点 一会儿用
查看字符占用字节
select
userenv('language'),
dump('我'),
length('我'), --字符数
lengthb('我'), --字节数
vsize('我')
from dual;
to_char函数使用
9 代表一个数字
0 强迫0显示
$ 显示美元符号
L 强制显示一个当地的货币符号
. 显示一个小数点
, 显示一个千分位分隔符号
三、开始说采坑的过程
3.1插入数据 发现问题
简单说下吧,刚刚代码窗口已经关掉了。
我设计的这个主键字段是varchar2(2)
插入的数据使用了to_char()函数做了转换
以前只拿这个转过日期,没转过数字---->字符串
to_char(1,'99')
我认为这个单纯的1到字符串1肯定是占一个字节啊,但是系统给我报了字符串缓冲区不够的报错。我一开始以为是别的原因,百思不得其解,这时候我还没意识到问题,然后把字段值加大了而已,解决了问题。
3.2插入一个外键的数据 再次发现问题
这么说吧,我的A表有一个记录主键是‘1’
我的B表关联了这个A表
我在B表插入记录时 我写的明明就是1 但是报错了
违反完整约束条件 (TUSTER.SYS_C007187) - 未找到父项关键字
我更加百思不得其解了,折腾了可能得一个多小时吧才醒悟
四、解决问题 涨知识 提升自己
4.1单纯的查下字节数 看看到底有没有问题
select lengthb('1') from dual;--结果是1
select lengthb(TO_CHAR(1,'99')) from dual;--结果是3
select lengthb(TO_CHAR(1,'9')) from dual;--结果是2
看到这大概也就明白咋回事了
其实我是看的可视化数据库先发现的问题,来我们看下可视化的数据库
为啥这个4这么优秀呢,当时4和5都是带空格的,我真的没看出来,我把5改了才看出来的,真的一下午把我整疯了。
4.2正式的说下原因和解决方案
网上查询资料发现,to_char转换指定格式时,字符串前面增加了一个空格,所以长度比指定格式长度增加了1,网上流传原因是:那个空格位置是放符号的,正的数字就空了,负的就是一个‘-’号而没有空格。
解决方法:用trim转换或者fm
trim掉返回结果中的前后空格
select lengthb(trim(TO_CHAR(1,'99'))) from dual;--结果是1
fm代表去掉返回结果中的前后空格和0
select lengthb(TO_CHAR(1,'fm99')) from dual;--结果是1