Récupérer les noms de colonne à partir de java.sql.ResultSet

233

Avec, java.sql.ResultSetexiste-t-il un moyen d'obtenir le nom d'une colonne en tant que Stringen utilisant l'index de la colonne? J'ai jeté un œil au document API mais je ne trouve rien.

BalusC
la source

Réponses:

372

Vous pouvez obtenir ces informations à partir des ResultSetmétadonnées. Voir ResultSetMetaData

par exemple

 ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
 ResultSetMetaData rsmd = rs.getMetaData();
 String name = rsmd.getColumnName(1);

et vous pouvez obtenir le nom de la colonne à partir de là. Si tu fais

select x as y from table

alors rsmd.getColumnLabel()vous obtiendrez le nom d'étiquette Récupéré aussi.

Brian Agnew
la source
22
Voir aussi rsmd.getColumnLabelsi vous récupérez des colonnes avec des étiquettes (par exempleSELECT columnName AS ColumnLabel
T30
15
Vous pourriez être surpris de voir le nombre de colonnes commencer à 1. Vous pouvez parcourir les noms de colonnes avecfor (int i = 1; i <= rsmd.getColumnCount(); i++) String name = rsmd.getColumnName(i);
Alphaaa
Renvoie getColumnName()le nom de la colonne d'origine s'il n'utilise pas la ASdénomination d'alias?
membersound
2
@membersound Oui, comme indiqué dans son Javadoc : "Si un SQL ASn'est pas spécifié, la valeur renvoyée par getColumnLabelsera la même que la valeur retournée par la getColumnNameméthode." . Dans presque tous les cas, vous devez utiliser à la getColumnLabelplace de getColumnName.
Mark Rotteveel
1
Cela échouera si la table est vide.
andronix
140

En plus des réponses ci-dessus, si vous travaillez avec une requête dynamique et que vous voulez les noms des colonnes mais que vous ne savez pas combien de colonnes il y a, vous pouvez utiliser l'objet ResultSetMetaData pour obtenir le nombre de colonnes en premier, puis les parcourir .

Modification du code de Brian:

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();

// The column count starts from 1
for (int i = 1; i <= columnCount; i++ ) {
  String name = rsmd.getColumnName(i);
  // Do stuff with name
}
Cyntech
la source
n'est-ce pas? for (int i = 1; i <= columnCount + 1; i ++) {...}
Martin
3
@Martin Non, car cela tentera d'obtenir la colonne n + 1 qui n'existe pas. Si vous voulez être absolument concis, ce serait le cas i <= columnCount.
Cyntech
21

Vous pouvez utiliser l'objet ResultSetMetaData ( http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html ) pour cela, comme ceci:

ResultSet rs = stmt.executeQuery("SELECT * FROM table");
ResultSetMetaData rsmd = rs.getMetaData();
String firstColumnName = rsmd.getColumnName(1);
Simon
la source
1
merci cela m'a aidé ... je l'ai utilisé comme: resultSet.getString (resultSet.findColumn ("fullname"))
C Sharper
Limitez les enregistrements récupérés à 1. Sinon, si la table est trop volumineuse, une surcharge inutile alors. Par exemple pour la base de données: utilisez la requête "SELECT * FROM table SAMPLE 1"
josepainumkal
11

Cette question est ancienne, tout comme les bonnes réponses précédentes. Mais ce que je cherchais quand j'ai trouvé ce sujet était quelque chose comme cette solution. Espérons que cela aide quelqu'un.

// Loading required libraries    
import java.util.*;
import java.sql.*;

public class MySQLExample {
  public void run(String sql) {
    // JDBC driver name and database URL
    String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    String DB_URL = "jdbc:mysql://localhost/demo";

    // Database credentials
    String USER = "someuser"; // Fake of course.
    String PASS = "somepass"; // This too!

    Statement stmt = null;
    ResultSet rs = null;
    Connection conn = null;
    Vector<String> columnNames = new Vector<String>();

    try {
      // Register JDBC driver
      Class.forName(JDBC_DRIVER);

      // Open a connection
      conn = DriverManager.getConnection(DB_URL, USER, PASS);

      // Execute SQL query
      stmt = conn.createStatement();
      rs = stmt.executeQuery(sql);
      if (rs != null) {
        ResultSetMetaData columns = rs.getMetaData();
        int i = 0;
        while (i < columns.getColumnCount()) {
          i++;
          System.out.print(columns.getColumnName(i) + "\t");
          columnNames.add(columns.getColumnName(i));
        }
        System.out.print("\n");

        while (rs.next()) {
          for (i = 0; i < columnNames.size(); i++) {
            System.out.print(rs.getString(columnNames.get(i))
                + "\t");

          }
          System.out.print("\n");
        }

      }
    } catch (Exception e) {
      System.out.println("Exception: " + e.toString());
    }

    finally {
      try {
        if (rs != null) {
          rs.close();
        }
        if (stmt != null) {
          stmt.close();
        }
        if (conn != null) {
          conn.close();
        }
      } catch (Exception mysqlEx) {
        System.out.println(mysqlEx.toString());
      }

    }
  }
}
Ronald Weidner
la source
5

SQLite 3

Utilisation de getMetaData ();

DatabaseMetaData md = conn.getMetaData();
ResultSet rset = md.getColumns(null, null, "your_table_name", null);

System.out.println("your_table_name");
while (rset.next())
{
    System.out.println("\t" + rset.getString(4));
}

EDIT: Cela fonctionne aussi avec PostgreSQL

Sedrick
la source
Je l'ai essayé sur une base de données teradata et j'ai obtenu l'erreur "[Base de données Teradata] [TeraJDBC 16.20.00.02] [Erreur 9719] [SQLState HY000] La fonctionnalité QVCI est désactivée."
josepainumkal
2
import java.sql.*;

public class JdbcGetColumnNames {

    public static void main(String args[]) {
        Connection con = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/komal", "root", "root");

            st = con.createStatement();

            String sql = "select * from person";
            rs = st.executeQuery(sql);
            ResultSetMetaData metaData = rs.getMetaData();

            int rowCount = metaData.getColumnCount();

            System.out.println("Table Name : " + metaData.getTableName(2));
            System.out.println("Field  \tDataType");

            for (int i = 0; i < rowCount; i++) {
                System.out.print(metaData.getColumnName(i + 1) + "  \t");
                System.out.println(metaData.getColumnTypeName(i + 1));
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Nom de la table: personne Champ DataType id VARCHAR cname VARCHAR dob DATE

Deep Rathod
la source
1

Lorsque vous avez besoin des noms de colonne, mais que vous ne souhaitez pas récupérer les entrées:

PreparedStatement stmt = connection.prepareStatement("SHOW COLUMNS FROM `yourTable`");

ResultSet set = stmt.executeQuery();

//store all of the columns names
List<String> names = new ArrayList<>();
while (set.next()) { names.add(set.getString("Field")); }

REMARQUE: ne fonctionne qu'avec MySQL

Hunter S
la source
1
Seulement cela a fonctionné pour moi !!. Il fallait que je descende pour ça. Je ne sais pas pourquoi getColumnName (i) & getColumnLabel (i), m'a récupéré des données étranges inattendues. Merci beaucoup!
VipiN Negi
Heureux que cela vous ait aidé!
Hunter S
1
while (rs.next()) {
   for (int j = 1; j < columncount; j++) {
       System.out.println( rsd.getColumnName(j) + "::" + rs.getString(j));      
   }
}
Jagadish Chenna
la source
6
S'il vous plaît, pouvez-vous étendre votre réponse avec une explication plus détaillée? Ce sera très utile pour comprendre. Je vous remercie!
vezunchik
1

Les instructions SQL qui lisent les données d'une requête de base de données renvoient les données dans un jeu de résultats. L'instruction SELECT est la méthode standard pour sélectionner des lignes dans une base de données et les afficher dans un jeu de résultats. L' **java.sql.ResultSet**interface représente l'ensemble de résultats d'une requête de base de données.

  • Méthodes d'obtention: utilisées pour afficher les données dans les colonnes de la ligne actuelle pointées par le curseur.

En utilisant MetaData of a result set to fetch the exact column count

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
boolean b = rsmd.isSearchable(1);

http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html

et encore plus pour le lier à la table de modèle de données

public static void main(String[] args) {
    Connection conn = null;
    Statement stmt = null;
    try {
        //STEP 2: Register JDBC driver
        Class.forName("com.mysql.jdbc.Driver");

        //STEP 3: Open a connection
        System.out.println("Connecting to a selected database...");
        conn = DriverManager.getConnection(DB_URL, USER, PASS);
        System.out.println("Connected database successfully...");

        //STEP 4: Execute a query
        System.out.println("Creating statement...");
        stmt = conn.createStatement();

        String sql = "SELECT id, first, last, age FROM Registration";
        ResultSet rs = stmt.executeQuery(sql);
        //STEP 5: Extract data from result set
        while(rs.next()){
            //Retrieve by column name
            int id  = rs.getInt("id");
            int age = rs.getInt("age");
            String first = rs.getString("first");
            String last = rs.getString("last");

            //Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);
        }
        rs.close();
    } catch(SQLException se) {
        //Handle errors for JDBC
        se.printStackTrace();
    } catch(Exception e) {
        //Handle errors for Class.forName
        e.printStackTrace();
    } finally {
        //finally block used to close resources
        try {
            if(stmt!=null)
                conn.close();
        } catch(SQLException se) {
        } // do nothing
        try {
            if(conn!=null)
                conn.close();
        } catch(SQLException se) {
            se.printStackTrace();
        } //end finally try
    }//end try
    System.out.println("Goodbye!");
}//end main
//end JDBCExample

très beau tutoriel ici: http://www.tutorialspoint.com/jdbc/

ResultSetMetaData meta = resultset.getMetaData();  // for a valid resultset object after executing query

Integer columncount = meta.getColumnCount();

int count = 1 ; // start counting from 1 always

String[] columnNames = null;

while(columncount <=count) {
    columnNames [i] = meta.getColumnName(i);
}

System.out.println (columnNames.size() ); //see the list and bind it to TableModel object. the to your jtbale.setModel(your_table_model);
Daniel Adenew
la source
0

@Cyntech a raison.

Dans le cas où votre table est vide et vous devez toujours obtenir les noms de colonne de table, vous pouvez obtenir votre colonne en tant que type Vector, voir ce qui suit:

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();

Vector<Vector<String>>tableVector = new Vector<Vector<String>>(); 
boolean isTableEmpty = true;
int col = 0;

 while(rs.next())
    {
      isTableEmpty = false;  //set to false since rs.next has data: this means the table is not empty
       if(col != columnCount)
          {
            for(int x = 1;x <= columnCount;x++){
                 Vector<String> tFields = new Vector<String>(); 
                 tFields.add(rsmd.getColumnName(x).toString());
                 tableVector.add(tFields);
             }
            col = columnCount;
          }
     } 


      //if table is empty then get column names only
  if(isTableEmpty){  
      for(int x=1;x<=colCount;x++){
           Vector<String> tFields = new Vector<String>(); 
           tFields.add(rsmd.getColumnName(x).toString());
           tableVector.add(tFields);
        }
      }

 rs.close();
 stmt.close();

 return tableVector; 
21stking
la source
0
ResultSet rsTst = hiSession.connection().prepareStatement(queryStr).executeQuery(); 
ResultSetMetaData meta = rsTst.getMetaData();
int columnCount = meta.getColumnCount();
// The column count starts from 1

String nameValuePair = "";
while (rsTst.next()) {
    for (int i = 1; i < columnCount + 1; i++ ) {
        String name = meta.getColumnName(i);
        // Do stuff with name

        String value = rsTst.getString(i); //.getObject(1);
        nameValuePair = nameValuePair + name + "=" +value + ",";
        //nameValuePair = nameValuePair + ", ";
    }
    nameValuePair = nameValuePair+"||" + "\t";
}
Rabi
la source
0

Si vous souhaitez utiliser Spring jdbctemplate et ne souhaitez pas traiter avec le personnel de connexion, vous pouvez utiliser les éléments suivants:

jdbcTemplate.query("select * from books", new RowCallbackHandler() {
        public void processRow(ResultSet resultSet) throws SQLException {
            ResultSetMetaData rsmd = resultSet.getMetaData();
            for (int i = 1; i <= rsmd.getColumnCount(); i++ ) {
                String name = rsmd.getColumnName(i);
                // Do stuff with name
            }
        }
    });
canapé selins
la source
0

U peut obtenir le nom et la valeur de la colonne de resultSet.getMetaData (); Ce code fonctionne pour moi:

Connection conn = null;
PreparedStatement preparedStatement = null;
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        conn = MySQLJDBCUtil.getConnection();
        preparedStatement = conn.prepareStatement(sql);
        if (params != null) {
            for (int i = 0; i < params.size(); i++) {
                preparedStatement.setObject(i + 1, params.get(i).getSqlValue());
            }
            ResultSet resultSet = preparedStatement.executeQuery();
            ResultSetMetaData md = resultSet.getMetaData();
            while (resultSet.next()) {
                int counter = md.getColumnCount();
                String colName[] = new String[counter];
                Map<String, Object> field = new HashMap<>();
                for (int loop = 1; loop <= counter; loop++) {
                    int index = loop - 1;
                    colName[index] = md.getColumnLabel(loop);
                    field.put(colName[index], resultSet.getObject(colName[index]));
                }
                rows.add(field);
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            }catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    return rows;
君主 不是 我
la source
0

Je sais, cette question est déjà répondue, mais probablement quelqu'un comme moi doit accéder à un nom de colonne à partir de DatabaseMetaDatapar étiquette au lieu d'index:

ResultSet resultSet = null;
DatabaseMetaData metaData = null;

    try {
        metaData  = connection.getMetaData();
        resultSet = metaData.getColumns(null, null, tableName, null);

        while (resultSet.next()){
            String name = resultSet.getString("COLUMN_NAME");
        }
    }
Pavlo Rozbytskyi
la source