如何基于JDBC Result Set创建表
我正在构建一个报告工具,我需要在远程数据库上执行查询并将结果集存储在我自己的数据库中(因为我没有远程数据库的写权限,我还需要缓存结果以防止进一步执行)。 此外,我需要此function,因此我可以将两个结果集连接在一起,并根据生成的结果生成结果。
现在,我的问题是我不知道如何基于jdbc ResultSet创建表。 是否有任何开源工具或脚本可以处理这个问题?
我的应用程序基于Spring 3.1.0并使用JDBC来查询本地和远程数据库。 我想存储结果的本地数据库是MySQL 5.5.20。 (这是一个存储在MySQL中的好主意吗?它能提供足够的性能吗?)
我们可以从结果集中提取最近的匹配结构并构造一个表。
但就表名,键,引擎类型,字段是否可为空等等而言,这不是精确的副本 。
以下代码段可帮助您以获得适当结果的方式继续操作。
String sql = "select * from visitors"; ResultSet rs = stmt.executeQuery( sql ); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); String tableName = null; StringBuilder sb = new StringBuilder( 1024 ); if ( columnCount > 0 ) { sb.append( "Create table " ).append( rsmd.getTableName( 1 ) ).append( " ( " ); } for ( int i = 1; i <= columnCount; i ++ ) { if ( i > 1 ) sb.append( ", " ); String columnName = rsmd.getColumnLabel( i ); String columnType = rsmd.getColumnTypeName( i ); sb.append( columnName ).append( " " ).append( columnType ); int precision = rsmd.getPrecision( i ); if ( precision != 0 ) { sb.append( "( " ).append( precision ).append( " )" ); } } // for columns sb.append( " ) " ); System.out.println( sb.toString() );
执行上面的部分代码,打印下面的字符串:
Create table visitors ( ip VARCHAR( 6 ), bro VARCHAR( 6 ) )
让我希望这有助于您继续前进。
类似的例子可以在以下位置找到: 使用ResultSet创建表???
更新1 :
如何处理仅存在于一个数据库中而不存在于另一个数据库中的类型
仅依赖于客户端应用程序的结果集时,您无法执行任何操作。
它应始终是主选择查询 ,从geometry
, address
等复合数据类型中选择适当的数据。
例子 : select addess.city, address.zipcode, x( geometry_column ), y( geometry_column )
举geometry
数据类型的示例 :
MySQL有空间支持的定义。 但我不确定它们与SQL Server的空间数据实现相比有多好。
geometry
是复合数据类型,因此无法通过直接查询检索。
您需要依赖函数来解析来自此类数据列的数据,并以可读 ,可识别的数据格式返回。
示例 : create table geom ( g geometry );
将结果集select g from geom
使用JAVA的select g from geom
转换为create table语句将导致g
列的unknwon
数据类型。
Create table geom ( g UNKNOWN )
在列g
上使用x(g)
, y(g)
坐标函数将返回正确且可接受的数据类型。
查询select x(g), y(g) from geom
将被转换为
Create table ( x(g) DOUBLE( 23, 31 ), y(g) DOUBLE( 23, 31 ) )
更新2 :
结果集可能是使用关系组合多个表生成的。 结果集字段也有可能由表达式及其别名组成。 因此,生成的列字段或别名的数据类型是动态决定的。 元数据不知道查询中表,列名及其原始/父数据类型的确切名称。
所以, 这是不可能的
- 表的单个名称并使用它。
- 父列的数据类型并使用它。
注意 :这也适用于所有其他跨数据库特定的数据类型,如NVARCHAR等。但是,请参阅此post,以替代MySQL中的NVARCHAR用法 。
在尝试这种动态数据迁移之前,客户端应用程序应该知道相应的数据类型并相应地使用它们。
另外,有关详细信息,请参阅Microsoft Access,MySQL和SQL Server的数据类型和范围 。
也许这有点棘手,但我认为它可能会对你有所帮助。
JDBC ResultSet对象具有getMetaData()
方法,该方法返回ResultSetMetaData
对象,该对象包含列名和列类型等。 你可以这样做:
ResultSet rs; String strSQL; ... strSQL = "create table tbl (" for(i=0;i0) strSQL += ", " strSQL += rs.getMetaData().getColumnName(i) + " " + rs.getMetaData().getColumnType(i); } strSQL+= ")" ....
您可以使用这种方式构建一个包含所需列的有效SQL DML。 在那之后,剩下的就是填充表格。
希望这对你有所帮助。
您可能基于执行select查询而拥有ResultSet。现在我们也可以执行单个查询来创建表,而不是获取ResultSet然后迭代它来创建表。
您的原始查询:
select * from table_name
而不是执行此操作并迭代,执行此操作
create table new_table_name as (select * from table_name)
在这里分析你可以在普通的SQL中这样做:
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
如果您想要一个通用的解决方案来处理数据库之间不同但数据类型相同的数据类型,则可以使用JDBCType 。 只需采用Ravinder Reddy解决方案并更改此行:
String columnType = rsmd.getColumnTypeName( i );
至
String columnType = JDBCType.valueOf(rsmd.getColumnType(i)).getName();
希望能帮助到你。