MySQL vérifie si une table existe sans lever d'exception

123

Quelle est la meilleure façon de vérifier si une table existe dans MySQL (de préférence via PDO en PHP) sans lever 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?

clops
la source

Réponses:

199

Je ne connais pas la syntaxe PDO pour cela, mais cela semble assez simple:

$result = mysql_query("SHOW TABLES LIKE 'myTable'");
$tableExists = mysql_num_rows($result) > 0;
nickf
la source
merci, j'ai totalement oublié que SHOW TABLES LIKE pourrait être limité à une seule table exacte
clops
53
PDO: $ tableExists = $ db-> query ("SHOW TABLES LIKE 'myTable'") -> rowCount ()> 0;
Reactgular
4
mysqli: if ($ db-> query ("SHOW TABLES LIKE 'myTable'") -> num_rows == 0) {// create table}
zPuls3
1
@MathewFoscarini, rowCount () peut ne pas être fiable dans ce cas, voir doc PHP .
datasn.io
4
Il n'y a plus de support pour les mysql_*fonctions, elles sont officiellement obsolètes , ne sont plus maintenues et seront supprimées à l'avenir. Vous devez mettre à jour votre code avec PDO ou MySQLi pour garantir la fonctionnalité de votre projet à l'avenir.
TRiG
39

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

SELECT COUNT(*)
FROM information_schema.tables 
WHERE table_schema = '[database name]' 
AND table_name = '[table name]';

Tous les résultats indiquent que la table existe.

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

Michael Todd
la source
il me manque peut-être quelque chose, mais pourquoi utiliseriez-vous cette méthode sur SHOW TABLES?
nickf
1
@nickf Cela fait partie de la norme ansi, donc c'est portable entre différents rdbms.
troelskn
@nickf: Cela fonctionne également sur des bases de données autres que MySQL. Cela inclut PostgreSQL et SQL Server pour autant que je sache.
Powerlord
se demandant s'il s'agit d'un exploit de sécurité, vous pouvez interroger des informations à partir de bases de données auxquelles vous n'êtes pas connecté ...
Talvi Watia
3
Il n'y a aucun risque pour la sécurité - Les requêtes adressées à la base de données information_schema afficheront uniquement les tables sur lesquelles l'utilisateur connecté a des privilèges.
Warren Rumak
8

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

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

J'espère que ça aide.

Attention: comme suggéré par @jcaron, cette fonction pourrait être vulnérable aux attacs sqlinjection, alors assurez-vous que votre $tablevar est propre ou mieux utilisez des requêtes paramétrées.

Falk
la source
Seulement si vous laissez quelqu'un remplir la variable $ table, toutes les variables d'une instruction SQL ne sont pas dangereuses, seulement si vous obtenez les données de sources non fiables. Bien sûr, vous êtes responsable de la manière dont vous utilisez la fonction et effectuez le filtrage. il n'est pas nécessaire de voter contre cette réponse.
Falk
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 se retrouvera avec 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 aucune raison de ne pas le faire ici, c'est juste une mauvaise pratique.
jcaron
Que diriez-vous d'ajouter un real_escape_string?
Falk
Utilisez des requêtes paramétrées et évitez les histoires d'horreur.
jcaron
4

Ceci est affiché simplement si quelqu'un vient chercher cette question. Même si on lui a répondu un peu. Certaines des réponses le rendent plus complexe qu'il ne devait l'être.

Pour mysql * j'ai utilisé:

if (mysqli_num_rows(
    mysqli_query(
                    $con,"SHOW TABLES LIKE '" . $table . "'")
                ) > 0
        or die ("No table set")
    ){

Dans PDO j'ai utilisé:

if ($con->query(
                   "SHOW TABLES LIKE '" . $table . "'"
               )->rowCount() > 0
        or die("No table set")
   ){

Avec cela, je pousse simplement la condition else dans ou. Et pour mes besoins, j'ai simplement besoin de mourir. Bien que vous puissiez définir ou à d'autres choses. Certains pourraient préférer le if / else if / else. Ce qui consiste alors à supprimer ou et à fournir ensuite if / else if / else.

Ésotérique
la source
3

Voici ma solution que je préfère lors de l'utilisation de procédures stockées. Fonction mysql personnalisée pour vérifier que 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('you_table_name') as _exists
Erandac
la source
2

Comme un "Afficher les tables" peut être lent sur des bases de données plus volumineuses, je recommande d'utiliser "DESCRIBE" et de vérifier si vous obtenez true / false en conséquence

$tableExists = mysqli_query("DESCRIBE `myTable`");
Martin Lisicki
la source
D'après ce que j'ai lu si «SHOW» devient inefficace, alors «information_schema» est plus préféré que «DESCRIBE».
Esoterica
-1
$q = "SHOW TABLES";
$res = mysql_query($q, $con);
if ($res)
while ( $row = mysql_fetch_array($res, MYSQL_ASSOC) )
{
    foreach( $row as $key => $value )
    {
        if ( $value = BTABLE )  // BTABLE IS A DEFINED NAME OF TABLE
            echo "exist";
        else
            echo "not exist";
    }
}
Beurre Namkeen
la source
2
Veuillez ajouter un commentaire précis pour le code afin de fournir la meilleure qualité de réponse. Le simple fait de coller du code ne dit pas grand-chose à l'auteur de la question.
Jakub Matczak
5
C'est en fait horrible. Donc, s'il y a 50 000 tables, vous chargez toutes les tables, parcourez chacune d'elles pour trouver si la table correcte existe?
Rohit Chopra
-1

Cadre Zend

public function verifyTablesExists($tablesName)
    {
        $db = $this->getDefaultAdapter();
        $config_db = $db->getConfig();

        $sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{$config_db['dbname']}'  AND table_name = '{$tablesName}'";

        $result = $db->fetchRow($sql);
        return $result;

    }
gilcierweb
la source
-1

Si la raison de vouloir faire cela est la création de table conditionnelle, alors 'CREATE TABLE IF NOT EXISTS' semble idéal pour le travail. Jusqu'à ce que je découvre cela, j'ai utilisé la méthode «DESCRIBE» ci-dessus. Plus d'informations ici: MySQL "CREATE TABLE IF NOT EXISTS" -> Erreur 1050

Robin Andrews
la source
-9

Pourquoi vous rendez-vous si difficile à comprendre?

function table_exist($table){ 
    $pTableExist = mysql_query("show tables like '".$table."'");
    if ($rTableExist = mysql_fetch_array($pTableExist)) {
        return "Yes";
    }else{
        return "No";
    }
} 
Hamed
la source