126 votes

Vérifier si une table MySQL existe sans déclencher d'exception

Quel est le meilleur moyen de vérifier si une table existe dans MySQL (de préférence via PDO en PHP) sans générer d'exception. Je n'ai pas envie d'analyser les résultats de "SHOW TABLES LIKE", et cetera. Il doit y avoir une sorte de requête booléenne?

202voto

nickf Points 185423

Interroger la base de données information_schema à l'aide d'une instruction préparée semble être la solution la plus fiable et sécurisée.

$sql = "SELECT 1 FROM information_schema.tables 
        WHERE table_schema = database() AND table_name = ?";
$stmt =  $pdo->prepare($sql);
$stmt->execute([$tableName]);
$exists = (bool)$stmt->fetchColumn();

0 votes

Merci, j'ai totalement oublié que SHOW TABLES LIKE pouvait être limité à une seule table exacte seulement.

54 votes

PDO : $tableExists = $db->query("SHOW TABLES LIKE 'myTable'")->rowCount() > 0;

4 votes

Mysqli : if ($db->query("SHOW TABLES LIKE 'myTable'")->num_rows==0) { // create table }

40voto

Michael Todd Points 9384

Si vous utilisez MySQL 5.0 et ultérieur, vous pouvez essayer :

SÉLECTIONNER COUNT(*)
DE information_schema.tables 
OÙ table_schema = '[nom de la base de données]' 
ET table_name = '[nom de la table]';

Tout résultat indique que la table existe.

De : http://www.electrictoolbox.com/check-if-mysql-table-exists/

0 votes

Peut-être que je rate quelque chose, mais pourquoi utiliseriez-vous cette méthode plutôt que SHOW TABLES?

1 votes

@nickf Il fait partie de la norme ANSI, donc il est portable entre différents systèmes de gestion de bases de données.

0 votes

@nickf : Cela fonctionne également sur d'autres bases de données que MySQL. Cela inclut PostgreSQL et SQL Server autant que je puisse dire.

8voto

Falk Points 69

En utilisant mysqli, j'ai créé la fonction suivante. En supposant que vous ayez une instance mysqli appelée $con.

function table_exist($con, $table){
    $table = $con->real_escape_string($table);
    $sql = "show tables like '".$table."'";
    $res = $con->query($sql);
    return ($res->num_rows > 0);
}

J'espère que cela vous aidera.

Avertissement : comme suggéré par @jcaron, cette fonction pourrait être vulnérable aux attaques par injection SQL, assurez-vous donc que votre variable $table est propre ou encore mieux, utilisez des requêtes paramétrées.

0 votes

Seulement si vous laissez quelqu'un remplir la variable $table, pas chaque variable à l'intérieur d'une instruction sql est dangereuse, seulement si vous obtenez les données à partir de sources non fiables. Bien sûr, vous êtes responsable de la façon dont vous utilisez la fonction et de la filtration. Il n'est pas nécessaire de voter négativement pour cette réponse.

0 votes

Si vous publiez du code comme celui-ci, quelqu'un finira par l'utiliser dans un endroit où les données n'ont pas été correctement vérifiées, et aboutira à une injection SQL. Utilisez simplement des requêtes paramétrées et vous éviterez tout problème, que les données aient été vérifiées ou non. Il n'y a absolument aucune raison de ne pas le faire ici, c'est simplement une mauvaise pratique.

0 votes

Que diriez-vous d'ajouter une fonction real_escape_string?

3voto

Esoterica Points 75

Ceci est publié simplement si quelqu'un cherche cette question. Même si elle a déjà été répondue un peu. Certaines réponses la rendent plus complexe qu'elle ne devrait l'être.

Pour mysql* j'ai utilisé :

if (mysqli_num_rows(
    mysqli_query(
                    $con, "SHOW TABLES LIKE '" . $table . "'")
                ) > 0
        or die ("Aucune table définie")
    ){

Avec PDO j'ai utilisé :

if ($con->query(
                   "SHOW TABLES LIKE '" . $table . "'"
               )->rowCount() > 0
        or die("Aucune table définie")
   ){

Avec cela, je pousse simplement la condition else dans or. Et pour mes besoins, j'ai juste besoin de die. Bien que vous puissiez définir or sur d'autres choses. Certains préfèrent peut-être le if/ else if/ else. Ce qui signifie alors supprimer or et ensuite fournir if/ else if/ else.

2voto

erandac Points 11

Voici ma solution préférée lors de l'utilisation de procédures stockées. Fonction MySQL personnalisée pour vérifier si la table existe dans la base de données actuelle.

delimiter $$

CREATE FUNCTION TABLE_EXISTS(_table_name VARCHAR(45))
RETURNS BOOLEAN
DETERMINISTIC READS SQL DATA
BEGIN
    DECLARE _exists  TINYINT(1) DEFAULT 0;

    SELECT COUNT(*) INTO _exists
    FROM information_schema.tables 
    WHERE table_schema =  DATABASE()
    AND table_name =  _table_name;

    RETURN _exists;

END$$

SELECT TABLE_EXISTS('votre_nom_de_table') as _exists

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