126

What is the best way to check if a table exists in MySQL (preferably via PDO in PHP) without throwing an exception. I do not feel like parsing the results of "SHOW TABLES LIKE" et cetera. There must be some sort of boolean query?

clops
  • 5,085
  • 6
  • 39
  • 53

10 Answers10

202

Querying the information_schema database using prepared statement looks like the most reliable and secure solution.

$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();
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
nickf
  • 537,072
  • 198
  • 649
  • 721
  • thanks, totally forgot that SHOW TABLES LIKE could be limited to one exact table only – clops Oct 06 '09 at 14:08
  • 54
    PDO: $tableExists = $db->query("SHOW TABLES LIKE 'myTable'")->rowCount() > 0; – Reactgular Dec 27 '12 at 17:32
  • 4
    mysqli : if ($db->query("SHOW TABLES LIKE 'myTable'")->num_rows==0) { // create table } – zPuls3 Oct 08 '14 at 06:30
  • 1
    @MathewFoscarini, rowCount() may not be reliable in this case, see [PHP doc](http://php.net/manual/en/pdostatement.rowcount.php). – datasn.io Apr 17 '15 at 03:14
  • 5
    There is **no more support** for `mysql_*` functions, they are [**officially deprecated**](https://wiki.php.net/rfc/mysql_deprecation), **no longer maintained** and will be [**removed**](http://php.net/manual/en/function.mysql-connect.php#warning) in the future. You should update your code with [PDO](http://php.net/pdo) or [MySQLi](http://php.net/mysqli) to ensure the functionality of your project in the future. – TRiG Jun 10 '16 at 10:39
40

If you're using MySQL 5.0 and later, you could try:

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

Any results indicate the table exists.

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

Michael Todd
  • 16,679
  • 4
  • 49
  • 69
  • maybe I'm missing something, but why would you use this method over SHOW TABLES? – nickf Oct 06 '09 at 14:06
  • 1
    @nickf It's part of the ansi standard, so it's portable between different rdbms'es. – troelskn Oct 06 '09 at 14:15
  • @nickf: It also works on databases other than MySQL. This includes PostgreSQL and SQL Server as far as I can tell. – Powerlord Oct 06 '09 at 14:16
  • wondering if this is a security exploit you can query information from databases you aren't connected to... – Talvi Watia Sep 17 '10 at 04:41
  • 3
    There is no security risk -- Queries to the information_schema database will only show tables that the connected user has privileges to. – Warren Rumak Oct 20 '11 at 17:05
  • FWIW, MySQL, Microsoft, and PostgreSQL are the *only* RDBMS brands that implement INFORMATION_SCHEMA according to the standard. Most other databases have system tables, but of their own design. – Bill Karwin Dec 31 '12 at 23:11
  • This is generally the correct answer unless you have a corrupt database (like myself), querying this is currently reporting different values than the tables I can actually query from, so its not a 100% guarantee in that situation. – ConstantineK Jun 14 '16 at 16:07
8

Using mysqli I've created following function. Assuming you have an mysqli instance called $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);
}

Hope it helps.

Warning: as sugested by @jcaron this function could be vulnerable to sqlinjection attacs, so make sure your $table var is clean or even better use parameterised queries.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Falk
  • 469
  • 1
  • 7
  • 19
  • Only if you let someone fill the $table var, not every var inside a sql statment is dangerous, only if you get the data from untrusted sources. Of course you are responsible of how you use the function and do the filtering. there is no need to downvote this answer. – Falk May 27 '16 at 11:35
  • If you publish code like this, someone will end up using it in a place where the data has not been properly checked, and will end up with an SQL injection. Just use parameterised requests, and you will avoid any issue, whether the data has been checked or not. There is no reason whatsoever to not do so here, it's just bad practice. – jcaron May 28 '16 at 11:56
  • How about adding a real_escape_string? – Falk May 28 '16 at 13:18
  • Use parameterised queries and avoid the horror stories. – jcaron May 28 '16 at 21:54
  • How real_escape_string is even remotely related to table names? – Your Common Sense May 09 '22 at 09:59
  • @YourCommonSense You should never trust the content of a variable when passing it to a SQL query. So my solution was to use real_escape_string to make sure that the variable $table can be placed in the query safely. But you should use parameterised queries as jcaron already said, so you can have peace of mind. – Falk Jul 04 '22 at 00:59
  • @YourCommonSense Imagine the variable $table contains something like `users'; '`. You have to think a bit about where and how many quote marks to put. – Falk Jul 04 '22 at 01:02
  • 1
    I beg my pardon, I confused this answer with another one. You are right, in this particular case real_escape_string could be used. – Your Common Sense Jul 04 '22 at 04:47
3

This is posted simply if anyone comes looking for this question. Even though its been answered a bit. Some of the replies make it more complex than it needed to be.

For mysql* I used :

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

In PDO I used:

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

With this I just push the else condition into or. And for my needs I only simply need die. Though you can set or to other things. Some might prefer the if/ else if/else. Which is then to remove or and then supply if/else if/else.

Esoterica
  • 151
  • 1
  • 9
2

Here is the my solution that I prefer when using stored procedures. Custom mysql function for check the table exists in current database.

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
  • 575
  • 5
  • 8
2

As a "Show tables" might be slow on larger databases, I recommend using "DESCRIBE " and check if you get true/false as a result

$tableExists = mysqli_query("DESCRIBE `myTable`");
John Green
  • 13,241
  • 3
  • 29
  • 51
  • From what I read if 'SHOW' becomes inefficient then 'information_schema' is more preferred over 'DESCRIBE'. – Esoterica Jul 16 '16 at 09:20
-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
    Please add accurate comment for the code to provide best quality of answer. Simply paste some code doesn't tell much to author of question. – Jakub Matczak Sep 18 '13 at 14:54
  • 5
    This is actually horrible. So if there are 50,000 tables, you would load all tables, loop through each one to find if the correct table exists? – Rohit Chopra Oct 15 '13 at 20:16
-1

Zend framework

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
  • 2,598
  • 1
  • 16
  • 15
-1

If the reason for wanting to do this is is conditional table creation, then 'CREATE TABLE IF NOT EXISTS' seems ideal for the job. Until I discovered this, I used the 'DESCRIBE' method above. More info here: MySQL "CREATE TABLE IF NOT EXISTS" -> Error 1050

Community
  • 1
  • 1
Robin Andrews
  • 3,514
  • 11
  • 43
  • 111
-9

Why you make it so hard to understand?

function table_exist($table){ 
    $pTableExist = mysql_query("show tables like '".$table."'");
    if ($rTableExist = mysql_fetch_array($pTableExist)) {
        return "Yes";
    }else{
        return "No";
    }
} 
RocketDonkey
  • 36,383
  • 7
  • 80
  • 84
Hamed
  • 3