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?

11 Answers 11

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();
Sign up to request clarification or add additional context in comments.

5 Comments

thanks, totally forgot that SHOW TABLES LIKE could be limited to one exact table only
PDO: $tableExists = $db->query("SHOW TABLES LIKE 'myTable'")->rowCount() > 0;
mysqli : if ($db->query("SHOW TABLES LIKE 'myTable'")->num_rows==0) { // create table }
@MathewFoscarini, rowCount() may not be reliable in this case, see PHP doc.
There is no more support for mysql_* functions, they are officially deprecated, no longer maintained and will be removed in the future. You should update your code with PDO or MySQLi to ensure the functionality of your project in the future.
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/

7 Comments

maybe I'm missing something, but why would you use this method over SHOW TABLES?
@nickf It's part of the ansi standard, so it's portable between different rdbms'es.
@nickf: It also works on databases other than MySQL. This includes PostgreSQL and SQL Server as far as I can tell.
wondering if this is a security exploit you can query information from databases you aren't connected to...
There is no security risk -- Queries to the information_schema database will only show tables that the connected user has privileges to.
|
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.

8 Comments

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.
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.
How about adding a real_escape_string?
Use parameterised queries and avoid the horror stories.
I beg my pardon, I confused this answer with another one. You are right, in this particular case real_escape_string could be used.
|
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.

Comments

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

Comments

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`");

1 Comment

From what I read if 'SHOW' becomes inefficient then 'information_schema' is more preferred over 'DESCRIBE'.
-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 Comments

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.
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?
-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;

    }

Comments

-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

Comments

-1

the problem with

CALL sys.table_exists(...

is you will need high privileges, and using OTHERS options (as say the title) maybe launch alert/warning/errors

Therefore after of you connect to your objective DB, you can run:

$db = 'database';
$Q = "SHOW TABLES WHERE `Tables_in_{$db}` LIKE 'the_table';";

the best with this QUERY is:

  1. very simple
  2. zero warnings (if table not exists)
  3. zero errors (if table not exists)

Comments

-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";
    }
} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.