MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 数据库 / 正文

Oracle中JDBC处理PreparedStatement处理Char问题浅析

2024-11-26 17:21 huorong 数据库 6 ℃ 0 评论

最近碰到一个奇怪的问题,同样的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

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言