通过JDBC获取数据库表结构的过程中碰到的问题及解决方案

原创
2013/12/25 17:25
阅读数 1.9K
  由于项目中采用的是oracle数据库,引入了ojdbc14-10.2.0.4.0.jar,所以,首先探索的就是oracle方面的解决方案。主要借助的是OracleResultSetMetaData.class这个类,下面是这部分的代码:
PreparedStatement ps = connection.prepareStatement(sql);
ps.execute();
OracleResultSetMetaData orsmd = (OracleResultSetMetaData) ps.getMetaData();
for(int i=1;i<=orsmd.getColumnCount();i++){
    System.out.print("字段名:"+orsmd.getColumnName(i));
    System.out.print("  字段类型:"+orsmd.getColumnTypeName(i));
    System.out.print("  字段长度:"+orsmd.getPrecision(i));
    System.out.println("  java类名:"+orsmd.getColumnClassName(i));
}

  需要注意的是,获得的orsmd的迭代是从1开始的,而不是习惯上的0。

  使用oracle提供的jar包的一个好处是它可以通过getColumnClassName()这个方法把数据库字段在java中对应的类型一并获得,省去了后期处理的一个步骤。

  但是,上面这种方法只适用于数据库是oracle的情况,所以下面是更通用的第二种方法:


//通用方法
DatabaseMetaData metaData = connection.getMetaData();
ResultSet resultSet = metaData.getColumns(null, null, "tableName", null);
while(resultSet.next()){
    System.out.print("列名:"+resultSet.getString("COLUMN_NAME"));
    System.out.print("  数据类型是:"+resultSet.getString("DATA_TYPE"));
    System.out.print("  类型名称是:"+resultSet.getString("TYPE_NAME"));
    System.out.print("  列大小是:"+resultSet.getString("COLUMN_SIZE"));
    System.out.println("  注释是:"+resultSet.getString("REMARKS"));
}

    这个方法是从网上搜来的,在数据库是mysql的时候没有任何问题,但是当数据库切换成oracle的时候,返回的resultSet始终是null。在百思不得其解/抓耳挠腮/掀桌子×N之后,终于发现问题出在  getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)  这个方法。这个方法里的第三个参数,也就是表名,它必须是大写...满满的都是怨念,我的oracle明明是/一定是/肯定是大小写不敏感...

    在解决上面这个问题后,很快又被第二个跳出来的bug调戏了,这货每次出表结构都要出双份或者三份,也就是同一个字段会返回两到三次.....于是乎.....百思不得其解/抓耳挠腮/掀桌子×N....终于通过google发现下面这一段:

In oracle, Connection.getMetaData() returns meta-data for the entire database, not just the schema you happen to be connected to. So when you supply null as the first two arguments to meta.getColumns(), you're not filtering the results for just your schema. You need to supply the name of the Oracle schema to one of the first two parameters of meta.getColumns(), probably the second one, e.g. meta.getColumns(null, "myuser", "EMPLOYEES", null); It's a bit irritating having to do this, but that's the way the Oracle folks chose to implement their JDBC driver.
    原来是因为在第二个参数为null的情况下,oracle会返回所有schema下的表的结构...然后,这个schema也就是第二个参数,也必须是大写。。。我在创建用户的时候 用的是小写。。我的oracle明明是/一定是/肯定是大小写不敏感...


    好吧,大小写的问题留待以后研究,问题先记录之...








展开阅读全文
打赏
1
13 收藏
分享
加载中

引用来自“GameKing”的评论

引用来自“ericsoul”的评论

sql不区分大小写,char字段内容区分大小写,但是oracle系统表记录的表名,字段名都是大小的。一般使用upper,

恩,这个我知道,我奇怪的是在平时查询的时候,数据库对表名大小写并不敏感,怎么在这个地方会有不一样的处理,不知道走的是什么流程...在数据库上还是只弱鸡...

呃sql中不区分大小写。字段区分大小写。你查的表名,字段名,oracle是维护在系统表里的。一般用户没有查询权限。但是可以使用系统接口也就是你调用的api
2013/12/26 18:09
回复
举报
GameKing博主

引用来自“ericsoul”的评论

sql不区分大小写,char字段内容区分大小写,但是oracle系统表记录的表名,字段名都是大小的。一般使用upper,

恩,这个我知道,我奇怪的是在平时查询的时候,数据库对表名大小写并不敏感,怎么在这个地方会有不一样的处理,不知道走的是什么流程...在数据库上还是只弱鸡...
2013/12/26 16:02
回复
举报
sql不区分大小写,char字段内容区分大小写,但是oracle系统表记录的表名,字段名都是大小的。一般使用upper,
2013/12/25 21:56
回复
举报
更多评论
打赏
3 评论
13 收藏
1
分享
返回顶部
顶部