MySQL verifica si existe una tabla sin lanzar una excepción

123

¿Cuál es la mejor manera de verificar si existe una tabla en MySQL (preferiblemente a través de PDO en PHP) sin lanzar una excepción? No tengo ganas de analizar los resultados de "SHOW TABLES LIKE", etc. Debe haber algún tipo de consulta booleana?

clops
fuente

Respuestas:

199

No conozco la sintaxis de PDO para esto, pero esto parece bastante sencillo:

$result = mysql_query("SHOW TABLES LIKE 'myTable'");
$tableExists = mysql_num_rows($result) > 0;
nickf
fuente
gracias, olvidé por completo que SHOW TABLES LIKE podría limitarse a una sola tabla exacta
clops
53
PDO: $ tableExists = $ db-> query ("MOSTRAR TABLAS COMO 'myTable'") -> rowCount ()> 0;
Reactgular
44
mysqli: if ($ db-> query ("MOSTRAR TABLAS COMO 'myTable'") -> num_rows == 0) {// crear tabla}
zPuls3
1
@MathewFoscarini, rowCount () puede no ser confiable en este caso, consulte el documento de PHP .
datasn.io
44
No hay más soporte para mysql_*funciones, están oficialmente en desuso , ya no se mantienen y se eliminarán en el futuro. Debe actualizar su código con PDO o MySQLi para garantizar la funcionalidad de su proyecto en el futuro.
TRiG
39

Si está utilizando MySQL 5.0 y versiones posteriores, puede intentar:

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

Cualquier resultado indica que la tabla existe.

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

Michael Todd
fuente
tal vez me falta algo, pero ¿por qué usarías este método sobre SHOW TABLES?
nickf
1
@nickf Es parte del estándar ansi, por lo que es portátil entre diferentes rdbms'es.
troelskn
@nickf: también funciona en bases de datos distintas de MySQL. Esto incluye PostgreSQL y SQL Server por lo que puedo decir.
Powerlord
preguntándose si esto es una vulnerabilidad de seguridad, puede consultar información de bases de datos a las que no está conectado ...
Talvi Watia
3
No hay riesgo de seguridad: las consultas a la base de datos information_schema solo mostrarán las tablas a las que el usuario conectado tiene privilegios.
Warren Rumak
8

Usando mysqli he creado la siguiente función. Asumiendo que tiene una instancia de mysqli llamada $ 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);
}

Espero eso ayude.

Advertencia: como lo sugiere @jcaron, esta función podría ser vulnerable a los ataques de sqlinjection, así que asegúrese de que su $tablevar esté limpia o incluso mejor use consultas parametrizadas.

Falk
fuente
Solo si deja que alguien complete la tabla $ var, no todas las variables dentro de una declaración sql son peligrosas, solo si obtiene los datos de fuentes no confiables. Por supuesto, usted es responsable de cómo utiliza la función y realiza el filtrado. no hay necesidad de rechazar esta respuesta.
Falk
Si publica un código como este, alguien terminará usándolo en un lugar donde los datos no se han verificado correctamente y terminará con una inyección de SQL. Simplemente use solicitudes parametrizadas y evitará cualquier problema, ya sea que los datos hayan sido verificados o no. No hay ninguna razón para no hacerlo aquí, es solo una mala práctica.
jcaron
¿Qué hay de agregar una cadena_escape_real?
Falk
Use consultas parametrizadas y evite las historias de terror.
jcaron
4

Esto se publica simplemente si alguien viene a buscar esta pregunta. A pesar de que ha sido respondido un poco. Algunas de las respuestas lo hacen más complejo de lo necesario.

Para mysql * utilicé:

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

En PDO utilicé:

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

Con esto solo empujo la condición else a o. Y para mis necesidades solo necesito morir. Aunque puede configurar o para otras cosas. Algunos pueden preferir el if / else if / else. Cuál es entonces eliminar o y luego suministrar if / else if / else.

Esoterica
fuente
3

Aquí está la solución que prefiero cuando uso procedimientos almacenados. La función mysql personalizada para verificar la tabla existe en la base de datos actual.

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
fuente
2

Como "Mostrar tablas" puede ser lento en bases de datos más grandes, le recomiendo usar "DESCRIBIR" y verificar si obtiene verdadero / falso como resultado

$tableExists = mysqli_query("DESCRIBE `myTable`");
Martin Lisicki
fuente
Por lo que leí si 'SHOW' se vuelve ineficiente, entonces 'information_schema' es más preferido 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";
    }
}
Mantequilla Namkeen
fuente
2
Agregue un comentario preciso para el código para proporcionar la mejor calidad de respuesta. Simplemente pegue algo de código no le dice mucho al autor de la pregunta.
Jakub Matczak
55
Esto es realmente horrible. Entonces, si hay 50,000 tablas, cargaría todas las tablas, recorrería cada una para encontrar si existe la tabla correcta.
Rohit Chopra
-1

Marco 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
fuente
-1

Si la razón para querer hacer esto es la creación de una tabla condicional, entonces 'CREAR TABLA SI NO EXISTE' parece ideal para el trabajo. Hasta que descubrí esto, utilicé el método 'DESCRIBIR' anterior. Más información aquí: MySQL "CREAR TABLA SI NO EXISTE" -> Error 1050

Robin Andrews
fuente
-9

¿Por qué lo haces tan difícil de entender?

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