如何基于JDBC Result Set创建表

时间:2012-06-29 19:46:28

标签: java mysql database jdbc resultset

我正在构建一个报告工具,我需要在远程数据库上执行查询并将结果集存储在我自己的数据库中(因为我没有远程数据库的写权限,我还需要缓存结果以防止进一步执行)。此外,我需要这种功能,因此我可以将两个结果集连接在一起,并根据生成的结果生成结果。

现在,我的问题是我不知道如何基于jdbc ResultSet创建表。是否有任何开源工具或脚本可以处理此问题?

我的应用程序基于Spring 3.1.0并使用JDBC来查询本地和远程数据库。我想存储结果的本地数据库是MySQL 5.5.20。 (这是一个存储在MySQL中的好主意吗?它能提供足够的性能吗?)

5 个答案:

答案 0 :(得分:8)

我们可以从结果集中提取最接近的匹配结构并构造一个表 但 根据表名,密钥,引擎类型,字段是否可以为空等等, 不能是完全复制品。

以下代码段可帮助您继续获取适当的结果。

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 ) )

让我希望这有助于您继续前进。

类似的例子可以在Create a table using ResultSet ???

找到

更新1

  

如何处理仅存在于一个数据库中且不存在于另一个数据库中的类型

仅依赖于客户端应用程序的结果集时,您无法执行任何操作 应该始终是主选择查询,从geometryaddress等复合数据类型中选择适当的数据。 考试select addess.city, address.zipcode, x( geometry_column ), y( geometry_column )

举例geometry数据类型
MySQL有Spatial Support的定义。但我不确定它们与SQL Server's implementation of Spatial Data相比有多好。

geometry是复合数据类型,因此无法通过直接查询检索 您需要依赖函数来解析来自此类数据列的数据,并以可读可识别数据格式返回。
示例create table geom ( g geometry );
使用JAVA将select g from geom的ResultSet转换为create table语句将导致列unknwon的{​​{1}}数据类型。

g

使用Create table geom ( g UNKNOWN ) x(g)列上的y(g)坐标函数将返回正确且可接受的数据类型。
查询g将转换为

select x(g), y(g) from geom

更新2
结果集可能是使用关系组合多个表生成的。结果集字段也有可能由表达式及其别名组成。因此,生成的列字段或别名的数据类型是动态决定的。元数据不知道查询中表,列名及其原始/父数据类型的确切名称。

所以,无法获得

  1. 表的单个名称并使用它。
  2. 父列的数据类型并使用它。
  3. 注意:这也适用于所有其他跨数据库的特定数据类型,例如 NVARCHAR 等。 但是,请参阅this posting for an alternative to NVARCHAR usage in MySQL

    在尝试进行此类动态数据迁移之前,客户端应用程序应负责了解相应的数据类型并相应地使用它们。

    另外,请参阅Data types and ranges for Microsoft Access, MySQL and SQL Server了解更多信息。

答案 1 :(得分:3)

也许这有点棘手,但我认为它可能对你有帮助。

JDBC ResultSet对象有一个getMetaData()方法,它返回一个ResultSetMetaData对象,其中包含列名和列类型等。你可以这样做:

ResultSet rs;
String strSQL;

...

strSQL = "create table tbl ("
for(i=0;i<rs.getMetaData().getColumnCount(),i++) {
    if(i>0)
        strSQL += ", "
    strSQL += rs.getMetaData().getColumnName(i) 
           + " " 
           + rs.getMetaData().getColumnType(i);
}
strSQL+= ")"

....

您可以使用这种方式构建一个包含所需列的有效SQL DML。在那之后,剩下的就是填充表格。

希望这会对你有所帮助。

答案 2 :(得分:1)

你可能有一个基于执行select查询的ResultSet。现在我们也可以执行单个查询来创建表,而不是获取ResultSet然后迭代它来创建表。

您的原始查询:

select * from table_name

执行此

,而不是执行此操作并进行迭代

create table new_table_name as (select * from table_name)

答案 3 :(得分:0)

如指定的here,您可以在纯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;

答案 4 :(得分:0)

如果您希望使用通用解决方案来处理数据库之间不同但Java中类型相同的数据类型,则可以使用 JDBCType 。 只需采用Ravinder Reddy解决方案并更改此行即可:

String columnType = rsmd.getColumnTypeName( i );

String columnType = JDBCType.valueOf(rsmd.getColumnType(i)).getName();

希望有帮助。