I want to check if a table with a specific name exists in a database I\'ve connected to using PHP and PDO.
It has to work on all database backends, like MySQL, SQLi
Here's a complete function for checking if a table exists.
/**
* Check if a table exists in the current database.
*
* @param PDO $pdo PDO instance connected to a database.
* @param string $table Table to search for.
* @return bool TRUE if table exists, FALSE if no table found.
*/
function tableExists($pdo, $table) {
// Try a select statement against the table
// Run it in try/catch in case PDO is in ERRMODE_EXCEPTION.
try {
$result = $pdo->query("SELECT 1 FROM $table LIMIT 1");
} catch (Exception $e) {
// We got an exception == table not found
return FALSE;
}
// Result is either boolean FALSE (no table found) or PDOStatement Object (table found)
return $result !== FALSE;
}
Note: PDO will only throw exceptions if it is told to, by default it is silent and throws no exceptions. Thats why we need to check the result as well. See PDO error handling at php.net
At first, I was using the accepted answer, but then I noticed it was failing with empty tables. Here is the code I'm using right now:
function DB_table_exists($db, $table){
GLOBAL $db;
try{
$db->query("SELECT 1 FROM $db.$table");
} catch (PDOException $e){
return false;
}
return true;
}
This code is an extract of my extension class for PDO. It will produce an error (and return false) if the table doesn't exist, but will succeed if the table exists and/or is empty.
This complete function is very similar to esbite's answer, but includes code to protect from SQL injection. Also, you may not get consistent results from the accepted answer when the table in question is empty.
/**
* This function checks if the table exists in the passed PDO database connection
* @param PDO $pdo - connection to PDO database table
* @param type $tableName
* @return boolean - true if table was found, false if not
*/
function tableExists(PDO $pdo, $tableName) {
$mrSql = "SHOW TABLES LIKE :table_name";
$mrStmt = $pdo->prepare($mrSql);
//protect from injection attacks
$mrStmt->bindParam(":table_name", $tableName, PDO::PARAM_STR);
$sqlResult = $mrStmt->execute();
if ($sqlResult) {
$row = $mrStmt->fetch(PDO::FETCH_NUM);
if ($row[0]) {
//table was found
return true;
} else {
//table was not found
return false;
}
} else {
//some PDO error occurred
echo("Could not check if table exists, Error: ".var_export($pdo->errorInfo(), true));
return false;
}
}
As part of your project, create a schema view.
For Oracle it would be something like
SELECT TABLE_NAME FROM ALL_TABLES
For Mysql:
SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'mydbname'
ETC..
And then run a query in your code against the view.
Do a query where you ask the database to create a table if it doesn't exist:
$string = "CREATE TABLE IF NOT EXISTS " .$table_name . " int(11) NOT NULL AUTO_INCREMENT,
`id` int(3) NOT NULL,
`blabla` int(2) NOT NULL,
`blabla1` int(2) NOT NULL,
`blabla3` varchar(3) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
AUTO_INCREMENT=1 ";
$sql = $conection->prepare($string);
$sql->execute();
Once you have your database handle via PDO, you can do this:
$tableExists = gettype($dbh->exec("SELECT count(*) FROM $table")) == 'integer';
Or wrap it in a function.
I tried messing around with try/catch at first, but even if the table did Not exist, there was no exception. Finally ended up with checking for the data type of the returned value from the dbh exec call. It's either an integer, if there is a match on the select count (even if there count is 0, or a boolean of false if there were no results.
I think this should work with all the database types that PDO supports, since the syntax is really simple.