90 votes

Vérifier si la table existe

J'ai une application de bureau avec une base de données intégrée. Lorsque j'exécute mon programme, je dois vérifier qu'une table spécifique existe, ou la créer si ce n'est pas le cas.

Étant donné un objet Connexion nommé conn pour ma base de données, comment pourrais-je vérifier ceci ?

0 votes

Veuillez être plus précis dans votre question.

124voto

RealHowTo Points 13117
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 votes

Assurez-vous que lorsque vous utilisez des noms de table, ils n'utilisent pas de caractères de motif comme le trait de soulignement, par exemple "employee_reports". J'ai déjà été confronté à des situations de ce type, car certaines implémentations de métadonnées utilisent la correspondance de motifs. Le mieux est de vérifier le jeu de résultats avec une simple instruction table.equals("employee_reports") dans votre if.

0 votes

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

0 votes

Veuillez noter que cette méthode déclenche le chargement d'informations sur l'ensemble de la base de données pour une connexion récemment créée. En fonction de la taille de la base de données, de la vitesse de connexion, cela peut prendre un certain temps, 2-5 secondes ou plus. Dans notre projet avec environ 2000 tests d'intégration, cela a donné un ralentissement pendant une heure (chaque test utilise un schéma nouvellement créé).

73voto

Brian Agnew Points 143181

Vous pouvez utiliser les métadonné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 aquí pour plus de détails. Notez également les mises en garde dans le JavaDoc .

15 votes

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

1 votes

@nolan6000 - noté et modifié. Thx

2 votes

Cette solution ne fonctionne pas si le nom de la table est fourni avec le schéma, donc soyez prudent avec cela. Pour fournir le schéma, vous devez utiliser meta.getTables("Schema_Name", null, "My_Table_Name", new String[] {"TABLE"})

12voto

nolan6000 Points 1511

En fait, je ne trouve aucune des solutions présentées ici entièrement complète, alors je vais ajouter la mienne. Rien de nouveau ici. Vous pouvez assembler tout cela à partir des autres solutions présentées et de divers commentaires.

Il y a au moins deux choses dont vous devrez vous assurer :

  1. Assurez-vous de passer le nom de la table à la méthode getTables() méthode , 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 le second vous demandez une liste de todo tables du serveur, puis de filtrer la liste liste localement. La première méthode est beaucoup plus rapide si vous ne recherchez qu'une seule seule table.

  2. Assurez-vous de vérifier le nom de la table dans le jeu de résultats avec une correspondance égal. La raison en est que le getTables() effectue une correspondance de motifs sur la requête pour la table et le _ est un caractère générique en 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 jeux de résultats. Depuis Java 7, il est préférable d'utiliser un déclaration d'essai avec les ressources pour ça.

Voici 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 réfléchir à ce que vous passez comme le types (4ème paramètre) sur votre getTables() appeler. Normalement, j'aurais juste laissé à null parce que vous ne voulez pas vous restreindre. Une VIEW est aussi bonne qu'une TABLE, n'est-ce pas ? De nos jours, de nombreuses bases de données vous permettent d'effectuer des mises à jour par le biais d'une VIEW. Se limiter à un type de TABLE n'est donc pas la meilleure solution dans la plupart des cas. YMMV.

1 votes

Vous devrez peut-être changer tName.equals(tableName) a tName.equals(tableName.toLowerCase()) cela ne fonctionnerait pas si tableName étaient en majuscules.

0 votes

La question ne porte pas sur une base de données particulière. Vous avez raison de dire que le cas doit être pris en compte, mais cela dépend de la base de données. Certaines bases de données peuvent même être modifiées. Par exemple, le serveur MS SQL prend en charge à la fois la sensibilité à la casse et la sensibilité à la casse, selon la façon dont vous définissez la valeur de la "COLLATION". Votre remarque est donc valable, mais il est difficile de trouver une solution générale qui fonctionne dans tous les cas.

6voto

wawiwa Points 58

Pour compléter le message de Gaby, mon jdbc getTables() pour Oracle 10g nécessite des majuscules pour fonctionner :

"employee" -> "EMPLOYEE"

Sinon, je recevrais une exception :

java.sql.SqlExcepcion épuisé resultset

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

1voto

Konstantin F Points 56
    /**
 * 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
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X