2010-05-31 11 views
67

J'ai une application de bureau avec une base de données intégrée. Quand j'exécute mon programme j'ai besoin de vérifier que la table spécifique existe, ou la créer sinon. Étant donné un objet Connection nommé conn pour ma base de données, comment puis-je vérifier cela?Vérifier si la table existe

+4

double possible de [Comment puis-je détecter une existence de table SQL en Java?] (Http://stackoverflow.com/questions/927807/how-can-i-detect-a-sql-tables-existence -in-java) – finnw

+0

S'il vous plaît être plus précis dans votre question. –

Répondre

57

Vous pouvez utiliser les méta-données disponibles:

DatabaseMetaData meta = con.getMetaData(); 
    ResultSet res = meta.getTables(null, null, "My_Table_Name", 
    new String[] {"TABLE"}); 
    while (res.next()) { 
    System.out.println(
     " "+res.getString("TABLE_CAT") 
     + ", "+res.getString("TABLE_SCHEM") 
     + ", "+res.getString("TABLE_NAME") 
     + ", "+res.getString("TABLE_TYPE") 
     + ", "+res.getString("REMARKS")); 
    } 

Voir here pour plus de détails. Notez également les mises en garde dans the JavaDoc.

+0

Merci !!!!!! – Dmitry

+8

Vous demandez toutes les tables du serveur, puis parcourez ces noms localement. Ce n'est pas très efficace si vous voulez juste vérifier si la table 'X' existe. Vous voudriez utiliser le 3ème argument de la méthode 'getTables()' !!! (plutôt que d'utiliser 'null' comme vous le faites) – peterh

+0

@ nolan6000 - noté et modifié. Thx –

105
DatabaseMetaData dbm = con.getMetaData(); 
// check if "employee" table is there 
ResultSet tables = dbm.getTables(null, null, "employee", null); 
if (tables.next()) { 
    // Table exists 
} 
else { 
    // Table does not exist 
} 
+3

Assurez-vous que lorsque vous utilisez des noms de table, il n'utilise pas de caractères de modèle comme le trait de soulignement, tels que "employee_reports". J'ai été pris par des situations comme celle-ci car certaines implémentations de métadonnées utilisent la correspondance de modèle. Il est préférable de revérifier le jeu de résultats avec une simple instruction table.equals ("employee_reports") dans votre if – Constantin

+0

Le même code fonctionne aussi pour postgres jdbc.Merci. – Ankur

6

Ajout au poste de Gaby, mes jdbc getTables() pour Oracle 10g exige que tous les bouchons pour travailler:

"employee" -> "EMPLOYEE"

Sinon je recevrais une exception:

java. sql.SqlExcepcion épuisé resultset

(même si "employee" est dans le schéma)

5

Je ne trouve aucune des solutions présentées ici pour être complète, alors j'ajouterai la mienne. Rien de nouveau ici. Vous pouvez assembler ceci à partir des autres solutions présentées plus divers commentaires.

Il y a au moins deux choses que vous devez vous assurer:

  1. Assurez-vous que vous passez le nom de la table à la getTables() method, plutôt que de passer une valeur nulle. Dans le premier cas, vous laissez le serveur de base de données filtrer le résultat pour vous, dans la seconde vous demandez une liste de toutes les tables du serveur, puis filtrer la liste localement. Le premier est beaucoup plus rapide si vous recherchez seulement une table unique .

  2. Assurez-vous de vérifier le nom de la table à partir du jeu de résultats avec une correspondance égale à . La raison en est que le getTables() fait correspondre le motif sur la requête pour la table et le caractère _ est un caractère générique dans SQL. Supposons que vous vérifiez l'existence d'une table nommée EMPLOYEE_SALARY. Vous obtiendrez alors une correspondance sur EMPLOYEESSALARY trop ce qui n'est pas ce que vous voulez.

Ohh, et n'oubliez pas de fermer ces résultats. Depuis Java 7, vous voudrez utiliser un try-with-resources statement pour cela.

est ici une solution complète:

public static boolean tableExist(Connection conn, String tableName) throws SQLException { 
    boolean tExists = false; 
    try (ResultSet rs = conn.getMetaData().getTables(null, null, tableName, null)) { 
     while (rs.next()) { 
      String tName = rs.getString("TABLE_NAME"); 
      if (tName != null && tName.equals(tableName)) { 
       tExists = true; 
       break; 
      } 
     } 
    } 
    return tExists; 
} 

Vous pouvez considérer ce que vous passez comme (4ème paramètre) paramètre types sur votre appel getTables(). Normalement, je voudrais juste laisser au null parce que vous ne voulez pas vous restreindre. Une vue est aussi bonne qu'une TABLE, non?Ces jours-ci, de nombreuses bases de données vous permettent de mettre à jour à travers une vue de sorte que vous restreindre à seulement le type TABLE n'est dans la plupart des cas pas le chemin à parcourir. YMMV.

+0

Vous devrez peut-être changer 'tName.equals (tableName)' en 'tName.equals (tableName.toLowerCase())', cela ne fonctionnerait pas si 'tableName' était en majuscule. – Searene

0
/** 
* Method that checks if all tables exist 
* If a table doesnt exist it creates the table 
*/ 
public void checkTables() { 
    try { 
     startConn();// method that connects with mysql database 
     String useDatabase = "USE " + getDatabase() + ";"; 
     stmt.executeUpdate(useDatabase); 
     String[] tables = {"Patients", "Procedures", "Payments", "Procedurables"};//thats table names that I need to create if not exists 
     DatabaseMetaData metadata = conn.getMetaData(); 

     for(int i=0; i< tables.length; i++) { 
      ResultSet rs = metadata.getTables(null, null, tables[i], null); 
      if(!rs.next()) { 
       createTable(tables[i]); 
       System.out.println("Table " + tables[i] + " created"); 
      } 
     } 
    } catch(SQLException e) { 
     System.out.println("checkTables() " + e.getMessage()); 
    } 
    closeConn();// Close connection with mysql database 
} 
Questions connexes