MySQL verifica se existe uma tabela sem lançar uma exceção


123

Qual é a melhor maneira de verificar se existe uma tabela no MySQL (de preferência via DOP no PHP) sem gerar uma exceção. Não sinto vontade de analisar os resultados de "MOSTRAR TABELAS COMO" et cetera. Deve haver algum tipo de consulta booleana?

Respostas:


199

Não conheço a sintaxe do DOP, mas isso parece bem direto:

$result = mysql_query("SHOW TABLES LIKE 'myTable'");
$tableExists = mysql_num_rows($result) > 0;

graças, esqueci completamente que MOSTRAR tabelas como poderia ser limitada a uma tabela exata apenas
Clops

53
PDO: $ tableExists = $ db-> query ("MOSTRAR TABELAS COMO 'minhaTabela'") -> rowCount ()> 0;
Reactgular

4
mysqli: if ($ db-> query ("MOSTRAR TABELAS COMO 'myTable'") -> num_rows == 0) {// create table}
zPuls3

1
@MathewFoscarini, rowCount () pode não ser confiável neste caso, consulte PHP doc .
datasn.io

4
Não há mais suporte para mysql_*funções, elas são oficialmente descontinuadas , não são mais mantidas e serão removidas no futuro. Você deve atualizar seu código com o PDO ou MySQLi para garantir a funcionalidade do seu projeto no futuro.
Trig

39

Se você estiver usando o MySQL 5.0 e posterior, você pode tentar:

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

Qualquer resultado indica que a tabela existe.

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


talvez esteja faltando alguma coisa, mas por que você usaria esse método em SHOW TABLES?
nickf

1
@nickf Faz parte do padrão ansi, por isso é portátil entre diferentes rdbms'es.
troelskn

@nickf: Ele também funciona em bancos de dados diferentes do MySQL. Isso inclui o PostgreSQL e o SQL Server, até onde eu sei.
Powerlord

perguntando se este é um exploit de segurança você pode consultar informações de bancos de dados que não estão conectados à ...
Talvi Watia

3
Não há risco de segurança - as consultas ao banco de dados information_schema mostrarão apenas tabelas às quais o usuário conectado tem privilégios.
Warren Rumak

8

Usando o mysqli eu criei a seguinte função. Supondo que você tenha uma instância do mysqli chamada $ 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 que ajude.

Atenção: como sugerido por @jcaron, esta função pode ser vulnerável a attets de sqlinjection, portanto, verifique se o seu $tablevar está limpo ou ainda melhor use consultas parametrizadas.


Somente se você deixar alguém preencher a tabela $ var, nem toda var dentro de uma declaração sql é perigosa, apenas se você obtiver os dados de fontes não confiáveis. Claro que você é responsável por como você usa a função e faz a filtragem. não há necessidade de votar negativamente nesta resposta.
Falk

Se você publicar um código como esse, alguém acabará usando-o em um local onde os dados não foram devidamente verificados e terminará com uma injeção de SQL. Basta usar solicitações parametrizadas e você evitará qualquer problema, independentemente de os dados terem sido verificados ou não. Não há nenhuma razão para não fazê-lo aqui, é apenas uma prática ruim.
jcaron

Que tal adicionar um real_escape_string?
Falk

Use consultas parametrizadas e evite as histórias de horror.
jcaron

4

Isto é publicado simplesmente se alguém vier à procura desta pergunta. Mesmo que tenha sido respondido um pouco. Algumas das respostas a tornam mais complexa do que precisava.

Para o mysql * eu usei:

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

Na DOP eu usei:

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

Com isso, apenas empurro a condição else para ou. E para as minhas necessidades, só preciso morrer. Embora você possa definir ou para outras coisas. Alguns podem preferir o if / else if / else. Que é então remover ou fornecer e então se / else if / else.


3

Aqui está a minha solução que eu prefiro ao usar procedimentos armazenados. Função personalizada do mysql para verificar se a tabela existe no banco de dados atual.

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

2

Como um "Mostrar tabelas" pode ser lento em bancos de dados maiores, recomendo usar "DESCRIBE" e verifique se você é verdadeiro / falso como resultado

$tableExists = mysqli_query("DESCRIBE `myTable`");

Pelo que li, se 'SHOW' se tornar ineficiente, então 'information_schema' é mais preferido do 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";
    }
}

2
Adicione comentários precisos ao código para fornecer a melhor qualidade de resposta. Basta colar algum código que não diz muito ao autor da pergunta.
Jakub Matczak

5
Isso é realmente horrível. Portanto, se houver 50.000 tabelas, você carregaria todas as tabelas, percorreria cada uma delas para descobrir se a tabela correta existe?
Rohit Chopra

-1

Estrutura 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;

    }


-9

Por que você torna tão 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";
    }
} 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.