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?

clops
fonte

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;
nickf
fonte
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/

Michael Todd
fonte
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.

Falk
fonte
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.

Esoterica
fonte
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
erandac
fonte
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`");
Martin Lisicki
fonte
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";
    }
}
Manteiga Namkeen
fonte
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;

    }
gilcierweb
fonte
-1

Se o motivo para querer fazer isso é a criação de tabela condicional, 'CREATE TABLE IF NOT EXISTS' parece ideal para o trabalho. Até descobrir isso, usei o método 'DESCRIBE' acima. Mais informações aqui: MySQL "CRIAR TABELA SE NÃO EXISTIR" -> Erro 1050

Robin Andrews
fonte
-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";
    }
} 
Hamed
fonte