2

レポート ツールを作成していて、リモート データベースでクエリを実行し、結果セットを自分のデータベースに保存する必要があります (リモート データベースへの書き込み権限がなく、それ以上実行されないように結果をキャッシュする必要があるため)。さらに、この機能が必要なので、2 つの結果セットを結合し、生成された結果に基づいて結果を生成できます。

今、私の問題は、jdbc ResultSet に基づいて CREATE TABLE する方法がわからないことです。これを処理するオープンソースのツールまたはスクリプトはありますか?

私のアプリケーションは Spring 3.1.0 に基づいており、JDBC を使用してローカル データベースとリモート データベースにクエリを実行します。結果を保存したいローカル データベースは MySQL 5.5.20 です。(これは MySQL に保存することをお勧めしますか? 十分なパフォーマンスを提供しますか?)

4

5 に答える 5

8

結果セットから最も近い一致する構造を抽出し、テーブルを作成できます。
ただし、これは、テーブル名、キー、エンジンタイプ、フィールドがnull許容かどうかなどの点で、正確なレプリカにすることはできません

次のコードスニペットは、適切な結果を得る方法で進めるのに役立ちます。

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

あるデータベースにのみ存在し、別のデータベースには存在しないタイプをどのように処理できますか

クライアント側のアプリケーションの結果セットのみに依存している場合は、何もできません。、などの複合データ型から適切なデータを選択する
のは、常にメインのselectクエリである必要があります。geometryaddress
select addess.city, address.zipcode, x( geometry_column ), y( geometry_column )

geometryデータ型の例を示すために
MySQLにはその空間サポートの定義があります。しかし、SQLServerの空間データの実装と比較してどれだけ優れているかはわかりません。

geometryは複合データ型であるため、直接クエリでは取得できません。
そのようなデータ列からのデータを解析し、読み取り可能識別可能なデータ形式で返す依存関数が必要です。
create table geom ( g geometry );
ResultSetselect g from geomをJAVAの使用からテーブルの作成ステートメントに変換すると、unknwon列のデータ型が得られますg

Create table geom ( g UNKNOWN )

を使用するx(g)と、y(g)列の座標関数はg適切で許容可能なデータ型を返します。
クエリselect x(g), y(g) from geomはに変換されます

Create table  ( x(g) DOUBLE( 23, 31 ), y(g) DOUBLE( 23, 31 ) ) 

更新2
結果セットは、リレーションを使用して複数のテーブルの組み合わせで生成される場合があります。結果セットフィールドが式とそのエイリアスで構成されている可能性もあります。したがって、結果の列フィールドまたはエイリアスのデータ型は動的に決定されます。メタデータは、テーブルの正確な名前、列名、およびクエリからの元の/親のデータ型を認識しません。

だから、得ることはできません

  1. テーブルの単一の名前とそれを使用します。
  2. 親列のデータ型とそれを使用します。

注:これは、 NVARCHARなどの他のすべてのクロスデータベース固有のデータ型にも適用できます。ただし、 MySQLでのNVARCHARの使用法の代わりに、この投稿を参照してください。

このような動的なデータ移行を試みる前に、同等のデータ型を知り、それに応じてそれらを使用するのはクライアントアプリケーションの責任である必要があります。

また、詳細については、Microsoft Access、MySQL、およびSQLServerのデータ型と範囲を参照してください。

于 2012-06-29T20:43:14.843 に答える
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 を構築できます。その後、テーブルにデータを入力するだけです。

これがお役に立てば幸いです。

于 2012-06-29T20:50:33.237 に答える
1

おそらく、選択クエリの実行に基づいて ResultSet を取得します。ResultSet を取得してから反復処理してテーブルを作成する代わりに、テーブル作成のために単一のクエリを実行することもできます。

元のクエリ:

select * from table_name

これを実行して繰り返す代わりに、これを実行します

create table new_table_name as (select * from table_name)

于 2013-09-18T09:02:50.560 に答える
0

ここで指定されているように、次のようにプレーン 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;
于 2012-06-29T19:49:05.070 に答える
0

データベース間では異なるが Java では同じタイプのデータのタイプを処理する一般的なソリューションが必要な場合は、JDBCTypeを使用できます。Ravinder Reddy ソリューションを使用して、次の行を変更するだけです。

String columnType = rsmd.getColumnTypeName( i );

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

それが役に立てば幸い。

于 2018-06-21T17:07:11.060 に答える