网站首页 > 数据库 / 正文
最近碰到一个奇怪的问题,同样的Java代码,在不同的数据库执行,结果集却不同?代码片段如下:
表的定义:
SAMPLE_TABLE ( ID INTEGER, NAME CHAR(20) )
java代码片段:
PreparedStatement pstmt = con.prepareStatement("INSERT INTO SAMPLE_TABLE VALUES (?, ?) ;");
pstmt.setInt(1, 100);
pstmt.setString(2, "Tom");
pstmt.execute();
pstmt.setInt(1, 200);
pstmt.setString(2, "Jerry");
pstmt.execute();
PreparedStatement pseq = con.prepareStatement("select * from sample_table where name=?");
pseq.setString(1,"Jerry");
ResultSet rs = pseq.executeQuery();
上面的片段,开始我觉得是自己写错了。于是用同样的代码的用MySQL数据库去验证代码是否有问题。但是结果是正确的。那么问题可能就出现在2个方面:1、setString传参时,获取参数;2、数据库对CHAR的处理方式不同。接下来就从两个方面来试着跟踪下,看看到底原因是什么导致的?
- JDBC中setString传参
上图是从“ojdbc6-11.2.0.3.jar”中看到的部分代码,其它数据库的jar包,我随机看了1、2个 ,这部分的实现代码,大同小异,基本上都是使用了 length()的参数。那么同样的代码,为什么实现的效果却不一样呢?接下来去数据库里看下,对比图如下:
从上面的两图中,我们很清楚的可以看到,length在检索数据时,MySQL和Oracle中的处理方式不一样。于是去查看了关于两个数据库中关于CHAR的相关处理方式。
- 数据库对CHAR的处理方式
MySQL
Oracle
上面是从相关的文档中,找到的关于CHAR的处理方式。
在写入时,两者的处理方式是是一样的。因为CHAR是定长的数据类型,所以写入数据时,不足定长的数据类型时,后面追加空格,补全定长。然后入库。eg:name(char20), name="Jack",因为“Jack”,只有四位,而name定义的char是20位,所以“Jack”入库时,会自动添加16个空格补够20位然后入库。
在读取时,MySQL默认情况下,会把后面的空格去掉,然后返回结果。Oracle因为没有找到相关的特别说明,但是从验证的结果来看,其并没有对数据的空格进行删除操作,而是把库里存的值,原样返回。
通过上面的分析,我们可以完美的解释,为什么同样的代码,在处理CHAR时,却又不同的结果。既然问题原因我们找到了,那么如何解决此类问题呢?推荐大家使用VARCHAR来代替CHAR。
参考连接:
https://dev.mysql.com/doc/refman/8.0/en/char.html
https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Data-Types.html#GUID-85E0A0DD-9E90-4AE1-9AD5-93C89FDCFC49
Tags:oracle insert into
猜你喜欢
- 2024-11-26 基于Percona XtraBackup 实现全备&增量备份与恢复
- 2024-11-26 ORACLE 错误代码及解决办法
- 2024-11-26 了解 Oracle 中单引号与双引号的用法,一篇文章教会你!
- 2024-11-26 WINCC保存数据到Oracle
- 2024-11-26 分享一个神奇现象--插入数据提示表不存在但却能查到这个表?
- 2024-11-26 MyBatis 批量插入使用 foreach 循环插入的优化,使用分片多线程
- 2024-11-26 oracle: PLSQL概念,关系运算符,顺序结构,分支结构,循环结构
- 2024-11-26 一个空格引发的“惨案“
- 2024-11-26 mybatis+oracle实现批量添加
- 2024-11-26 详解mysql数据库另类实现merge into语法的两种方式