2012-09-11 19 views
20

私は異なるタイプのデータを返すResultSetを持っています。クエリは動的に構築されるので、コンパイル時には、クエリが返す値の型がわかりません。JavaでResultSetMetaDataから異なるデータ型を取得するにはどうすればよいですか?

すべての結果が文字列であると仮定して、次のコードを記述しました。しかし、私はそれぞれの価値のタイプも手に入れたいです。これどうやってするの?

以下は私が書いたコードです。

while (reportTable_rst.next()) { 
    String column = reportTable_rst.getString(columnIterator); 
} 

この時点で、私は列の型を取得し、データ型に応じて値を取得したいと考えています。

+0

こんにちはすべて。これは将来の訪問者のための情報です。その列のデータ型に関係なくフィールド値を取得する必要がある場合は、挿入中にresultSetのgetObjectメソッドとPreparedStatementのsetObjectメソッドを使用できます。ここには例があります。 '一方(rsdata.next()) \t \t { \t \t \t(I = 0 int型、iはcol_sizeを<; Iは++)のため \t \t \t { \t \t \t \t columnValue = rsdata.getObject(I + 1) ; \t \t \t \t pstmtInsert = conRenameInfo.prepareStatement( "INSERT INTO" + "columnName +")VALUES(?) "); \t \t \t \t pstmtInsert.setObject(1、columnValue); \t \t \t \t pstmtInsert.executeUpdate(); \t \t \t} \t \t} – learner

答えて

30

ResultSetMetaData.getColumnType(int column)java.sql.Typesに見出さカラムタイプを指定int値を返します。

例:

Connection connection = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD); 
PreparedStatement statement = connection.prepareStatement(JDBC_SELECT); 
ResultSet rs = statement.executeQuery(); 
PrintStream out = System.out; 

if (rs != null) { 
    while (rs.next()) { 
     ResultSetMetaData rsmd = rs.getMetaData(); 
     for (int i = 1; i <= rsmd.getColumnCount(); i++) { 
      if (i > 1) { 
      out.print(","); 
      } 

      int type = rsmd.getColumnType(i); 
      if (type == Types.VARCHAR || type == Types.CHAR) { 
       out.print(rs.getString(i)); 
      } else { 
       out.print(rs.getLong(i)); 
      } 
     } 

     out.println(); 
    } 
} 
+0

たぶんニックピッキングだが、1つの質問:なぜ* whileループ内で* ResultSetMetaData *オブジェクトを取得するのか?私はそれがまだ同じであることを意味し、列名とその型も同じです。 ** ResultSetMetaData *オブジェクト**を** whileループの前に一度だけ取得することができます。 – informatik01

+0

'ResultSet'の反復がないと、' java.sql 'のような例外が発生します。SQLException:カーソルの位置が無効です。イテレーションはデフォルトで指定された方向または 'FORWARD'にカーソルを移動します。 –

+0

もちろん、次の行に反復/移動するには、 'rs.next()'を使用する必要があることを知っています。私は** ResultSetMetaData **オブジェクトについて言っていましたが、**同じ**ですし、反復する必要はありません。したがって、** resultSetMetaData **オブジェクト**を一度だけ**簡単に取り出すことができます。これは 'while'ループを入力する前に実行してください。例外はありません。 – informatik01

3

Toは、指定された列のSQL型を返します。

int ResultSetMetaData.getColumnType(int column)

指定された列のデータベース固有の型名を返します。

String ResultSetMetaData.getColumnTypeName(int column)

3
ResultSet rs; 
int column; 
..... 
ResultSetMetaData metadata = rs.getMetaData(); 
metadata.getColumnTypeName(column); // database specific type name 
metadata.getColumnType(column); // returns the SQL type 
1

私は上記の答えはループ内で起こっていないと思うし、細部にいくつかの欠如を持っています。このコードスニペットは、列名と対応するデータ型を表示するだけで改善できます。ここに完全に動作するコードは

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.SQLException; 

public class Test { 

    private static final String DRIVER = "com.mysql.jdbc.Driver"; 
    private static final String HOST = "192.168.56.101"; 
    private static final String PORT = "3316"; 
    private static final String CONNECTION_URL = "jdbc:mysql://"+HOST+":"+PORT+"/"; 
    private static final String USERNAME = "user"; 
    private static final String PASSWORD = "pwd"; 
    private static final String DATABASE = "db"; 
    private static final String TABLE = "table"; 
    private static final String QUERY = "select * from "+DATABASE+"."+TABLE+" where 1=0"; 

    public static void main(String[] args) throws ClassNotFoundException, SQLException { 
     Class.forName(DRIVER); 
     Connection con = DriverManager.getConnection (CONNECTION_URL , USERNAME, PASSWORD); 
     ResultSet rs = con.createStatement().executeQuery(QUERY); 
     if (rs != null) { 
      System.out.println("Column Type\t\t Column Name"); 

       ResultSetMetaData rsmd = rs.getMetaData(); 
       for (int i = 1; i <= rsmd.getColumnCount(); i++) { 
        System.out.println(rsmd.getColumnTypeName(i)+"\t\t\t"+rsmd.getColumnName(i)); 
      } 
     } 
    } 
} 
関連する問題