217

Is there a way to check if a table exists without selecting and checking values from it?

That is, I know I can go SELECT testcol FROM testtable and check the count of fields returned, but it seems there must be a more direct / elegant way to do it.

Jesse Nickles
  • 1,435
  • 1
  • 17
  • 25
Ben
  • 54,723
  • 49
  • 178
  • 224

19 Answers19

410

If you want to be correct, use INFORMATION_SCHEMA.

SELECT * 
FROM information_schema.tables
WHERE table_schema = 'yourdb' 
    AND table_name = 'testtable'
LIMIT 1;

Alternatively, you can use SHOW TABLES

SHOW TABLES LIKE 'yourtable';

If there is a row in the resultset, table exists.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • 3
    Yeah, that works nicely and is elegant, but still uses `SELECT...FROM` syntax...I was sort of looking for something like `EXISTS testtable` – Ben Jan 12 '12 at 01:48
  • 10
    The way Marc and myself stated to do it is the proper way. There is no 'exists' type statement MySql. 'Exists' in MySql is a clause which requires an operation such as SELECT, UPDATE, or DELETE. – doogle Jan 12 '12 at 01:51
  • @Steve The third option is not portable. – ta.speot.is Jan 12 '12 at 04:19
  • @todda.speot.is: not portable across MySQL versions? – Sergio Tulentsev Jan 12 '12 at 04:24
  • @SergioTulentsev Across most RDBMS' -- Oracle, SQL Server, MySQL, Postgres etc. `SELECT NULL FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG = 'YourDB' AND TABLE_NAME = 'YourTable'` is (as best I can tell) usable on Oracle/SQL/MySQL/Postgres etc. – ta.speot.is Jan 12 '12 at 04:28
  • @todda.speot.is: yeah, but this is tagged with `mysql`. Probably this is not an issue for him. But anyway, thanks for the reminder. – Sergio Tulentsev Jan 12 '12 at 04:30
  • 2
    @SergioTulentsev Regardless of the tag I prefer the portable way to the proprietary way. – ta.speot.is Jan 12 '12 at 04:31
  • @Steve, curious about your aversion to SELECT...FROM. Efficiency? In my own case I run CREATE TABLE IF NOT EXISTS first on every web hit. I wonder if it would be more efficient (CPU, memory) to (a) try to use the table normally and only CREATE if error, or (b) first test for the table's existence using one of the above Sergio methods. – Bob Stein Jan 08 '13 at 14:20
  • There's an issue with `SELECT 1 FROM testtable LIMIT 1;`. It will only return 1 when the table is exists and has rows in it. – filype Apr 02 '13 at 12:34
  • 1
    @Filype this is not really an issue, as he is only checking if the query succeeded or not. In the case where the table has no rows, the query will still succeed, just with an empty result set. – Bill Dami Aug 23 '13 at 14:00
  • Warning: if you use the `SHOW TABLES LIKE` form, remember that you may want to escape underscores (e.g., `SHOW TABLES LIKE 'my\_table\_xyz'`) – Walter Tross Jan 16 '14 at 13:42
  • Using INFORMATION_SCHEMA works for me because I need to check that both the Database and Table exists. – Ruben_PH Aug 04 '14 at 03:51
  • Regarding the 3rd option, why `LIKE` and not `=` (equals)? – AlikElzin-kilaka Apr 24 '15 at 17:10
  • @AlikElzin-kilaka, see http://dev.mysql.com/doc/refman/5.7/en/show-tables.html and http://dev.mysql.com/doc/refman/5.7/en/extended-show.html. You can do `SHOW TABLES WHERE Tables_in_mydatabase = 'tablename';` – Bill Karwin Aug 05 '16 at 00:59
  • But when using `SELECT 1 FROM testtable LIMIT 1;` It will return same row count for **table_1908** and **table_2008** even if **table_2008** does not exists. – Mahipalsinh Ravalji Aug 24 '16 at 18:00
  • This is great! Generaly `SHOW TABLES LIKE` will fail inside IF statemant but `SELECT 1 FROM testtable LIMIT 1;` will return `1` or `0` what is possible easy to check. `EXISTS()` also can be solution but is a bit slower. – Ivijan Stefan Stipić Nov 24 '17 at 08:19
  • 1
    @Sergio Tulentsev Do you know how reliable is `information_schema`? Is it always accessible? Does it require certain permission to be able to access this table? – checksum Mar 10 '18 at 15:32
  • Not safe enough for scripts on Python, for example. I ask just select * tables from information_schema... and then use *in* operator to find particular name:) https://xkcd.com/327/ – Wera Jul 16 '19 at 12:17
84
SELECT count(*)
FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = 'your_db_name') AND (TABLE_NAME = 'name_of_table')

if you get a non-zero count, the table exists.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 2
    I really don't get it what happened here. I've checked the answers, because I am doing it now, and it is true that Sergio Tulentsevs answer was earlier (1 mins) and offered 3 solutions, but this one is the most effective. Why should I select anything more or anything else what I want? I need a "boolean" 1/0 in this case. Is the table exists or not. I do not want to limit everything, I do not want to like anything, I do not want any errors. This should be the accepted answer. – vaso123 Mar 10 '17 at 00:06
  • 1
    Note that on a `TEMPORARY TABLE` this is not working. – Thomas Lobker Oct 11 '17 at 19:56
37

A performance comparison:

  • MySQL 5.0.77, on a db that has about 11,000 tables.
  • Selecting a non-recently-used table so it's not cached.
  • Averaged over 10 tries each. (Note: done with different tables to avoid caching).

322ms: show tables like 'table201608';

691ms: select 1 from table201608 limit 1;

319ms: SELECT count(*) FROM information_schema.TABLES WHERE (TABLE_SCHEMA = 'mydb') AND (TABLE_NAME = 'table201608');

Note if you're running this a lot -- like over many HTML requests in a short period -- the 2nd will be way faster since it'll be cached an average 200 ms or faster.

Ben
  • 54,723
  • 49
  • 178
  • 224
Ken Fricklas
  • 371
  • 3
  • 2
24

After reading all of the above, I prefer the following statement:

SELECT EXISTS(
       SELECT * FROM information_schema.tables 
       WHERE table_schema = 'db' 
       AND table_name = 'table'
);

It indicates exactly what you want to do and it actually returns a 'boolean'.

StationaryTraveller
  • 1,449
  • 2
  • 19
  • 31
  • 4
    this should the accepted answer. concise and simple – Dika Aug 29 '19 at 04:42
  • 1
    this does not return a Boolean, it returns a result set. var_dump: `mysqli_result Object ( [current_field] => 0 [field_count] => 1 [lengths] => [num_rows] => 1 [type] => 0 )` – camslice May 06 '20 at 00:20
18

You can query the INFORMATION_SCHEMA tables system view:

SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'databasename'
AND table_name = 'testtable';

If no rows returned, then the table doesn't exist.

doogle
  • 3,376
  • 18
  • 23
15

Here is a table that is not a SELECT * FROM

SHOW TABLES FROM `db` LIKE 'tablename'; //zero rows = not exist

Got this from a database pro, here is what I was told:

select 1 from `tablename`; //avoids a function call
select * from INFORMATION_SCHEMA.tables where schema = 'db' and table = 'table' // slow. Field names not accurate
SHOW TABLES FROM `db` LIKE 'tablename'; //zero rows = does not exist
Community
  • 1
  • 1
csukcc
  • 752
  • 7
  • 8
7

Rather than relying on errors, you can query INFORMATION_SCHEMA.TABLES to see if the table exists. If there's a record, it exists. If there's no record, it doesn't exist.

ta.speot.is
  • 26,914
  • 8
  • 68
  • 96
5

This modified solution from above does not require explicit knowledge of the current database. It is then more flexible.

SELECT count(*) FROM information_schema.TABLES WHERE TABLE_NAME = 'yourtable' 
AND TABLE_SCHEMA in (SELECT DATABASE());
Martin
  • 121
  • 1
  • 4
4

show tables like 'table_name'

if this returns rows > 0 the table exists

Stefan
  • 164
  • 1
  • 10
3

If reading this after 2019, note that MySQL 5.7 added a table_exists procedure that will determine if a table exists, including TEMPORARY TABLES.

Usage: Sets @exist to one of '', 'BASE TABLE', 'VIEW', 'TEMPORARY'

CALL sys.table_exists('db1', 't3', @exists);

Reference:

https://dev.mysql.com/doc/refman/5.7/en/sys-table-exists.html

Garr Godfrey
  • 8,257
  • 2
  • 25
  • 23
2

Just to add an extra way to do it, and depending on what you need it for you could use a handler for er_no_such_table error:1146 like this:

DELIMITER ;;
CREATE PROCEDURE `insert_in_my_table`(in my_var INT)
BEGIN
   -- Error number for table not found
   DECLARE CONTINUE HANDLER FOR 1146
   BEGIN
      -- table doesn't exists, do something...
      CREATE TABLE my_table(n INT);
      INSERT INTO my_table (n) values(my_var);
   END;
      -- table does exists, do something...
      INSERT INTO my_table (n) values(my_var);
END ;;
DELIMITER ;
eracuna
  • 102
  • 6
1

You can do something like below:

            string strCheck = "SHOW TABLES LIKE \'tableName\'";
            cmd = new MySqlCommand(strCheck, connection);
            if (connection.State == ConnectionState.Closed)
            {
                connection.Open();
            }
            cmd.Prepare();
            var reader = cmd.ExecuteReader();
            if (reader.HasRows)
            {                             
              Console.WriteLine("Table Exist!");
            }
            else
            {                             
              Console.WriteLine("Table does not Exist!");
            }
Manish Jain
  • 1,197
  • 1
  • 11
  • 32
1

Expanding this answer, one could further write a function that returns TRUE/FALSE based on whether or not a table exists:

CREATE FUNCTION fn_table_exists(dbName VARCHAR(255), tableName VARCHAR(255))
  RETURNS BOOLEAN
  BEGIN
    DECLARE totalTablesCount INT DEFAULT (
      SELECT COUNT(*)
      FROM information_schema.TABLES
      WHERE (TABLE_SCHEMA COLLATE utf8_general_ci = dbName COLLATE utf8_general_ci)
        AND (TABLE_NAME COLLATE utf8_general_ci = tableName COLLATE utf8_general_ci)
    );
    RETURN IF(
      totalTablesCount > 0,
      TRUE,
      FALSE
    );
END
;


SELECT fn_table_exists('development', 'user');
Nae
  • 14,209
  • 7
  • 52
  • 79
1

This compact method return 1 if exist 0 if not exist.

set @ret = 0; 
SELECT 1 INTO @ret FROM information_schema.TABLES 
         WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'my_table'; 
SELECT @ret;

You can put in into a mysql function

DELIMITER $$
CREATE FUNCTION ExistTable (_tableName varchar(255))
RETURNS tinyint(4)
SQL SECURITY INVOKER
BEGIN
  DECLARE _ret tinyint;
  SET _ret = 0;
  SELECT
    1 INTO _ret
  FROM information_schema.TABLES
  WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = _tablename LIMIT 1;
  RETURN _ret;
END
$$
DELIMITER ;

and call it

Select ExistTable('my_table');

return 1 if exist 0 if not exist.

MCO
  • 11
  • 1
0

None of the options except SELECT doesn't allow database name as used in SELECT, so I wrote this:

SELECT COUNT(*) AS cnt FROM information_schema.TABLES 
WHERE CONCAT(table_schema,".",table_name)="db_name.table_name";
Atis Lezdins
  • 59
  • 1
  • 1
0

I use this in php.

private static function ifTableExists(string $database, string $table): bool
    {
        $query = DB::select("
            SELECT 
                IF( EXISTS 
                    (SELECT * FROM information_schema.COLUMNS
                        WHERE TABLE_SCHEMA = '$database'
                        AND TABLE_NAME = '$table'
                        LIMIT 1),
                1, 0)
                AS if_exists
        ");

        return $query[0]->if_exists == 1;
    }
Raza
  • 3,147
  • 2
  • 31
  • 35
0

There are several issues to note with the answers here:

1) INFORMATION_SCHEMA.TABLES does not include TEMPORARY tables.

2) Using any type of SHOW query, i.e. SHOW TABLES LIKE 'test_table', will force the return of a resultset to the client, which is undesired behavior for checking if a table exists server-side, from within a stored procedure that also returns a resultset.

3) As some users mentioned, you have to be careful with how you use SELECT 1 FROM test_table LIMIT 1.

If you do something like:

SET @table_exists = 0;
SET @table_exists = (SELECT 1 FROM test_table LIMIT 1);

You will not get the expected result if the table has zero rows.

Below is a stored procedure that will work for all tables (even TEMPORARY).

It can be used like:

SET @test_table = 'test_table';
SET @test_db = NULL;
SET @does_table_exist = NULL;

CALL DoesTableExist(@test_table, @test_db, @does_table_exist);

SELECT @does_table_exist;

The code:

/*
    p_table_name is required
    p_database_name is optional
        if NULL is given for p_database_name, then it defaults to the currently selected database
    p_does_table_exist
        The @variable to save the result to

    This procedure attempts to
        SELECT NULL FROM `p_database_name`.`p_table_name` LIMIT 0;

    If [SQLSTATE '42S02'] is raised, then
        SET p_does_table_exist = 0
    Else
        SET p_does_table_exist = 1

    Info on SQLSTATE '42S02' at:
        https://dev.mysql.com/doc/refman/5.7/en/server-error-reference.html#error_er_no_such_table
*/

DELIMITER $$

DROP PROCEDURE IF EXISTS DoesTableExist
$$

CREATE PROCEDURE         DoesTableExist (
    IN p_table_name VARCHAR(64),
    IN p_database_name VARCHAR(64),
    OUT p_does_table_exist TINYINT(1) UNSIGNED
)
BEGIN
    /* 793441 is used in this procedure for ensuring that user variables have unique names */

    DECLARE EXIT HANDLER FOR SQLSTATE '42S02'
    BEGIN
        SET p_does_table_exist = 0
        ;
    END
    ;


    IF p_table_name IS NULL THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'DoesTableExist received NULL for p_table_name.';
    END IF;


    /* redirect resultset to a dummy variable */

    SET @test_select_sql_793441 = CONCAT(
        "SET @dummy_var_793441 = ("
            " SELECT"
                " NULL"
            " FROM ",
                IF(
                    p_database_name IS NULL,
                    "",
                    CONCAT(
                        "`",
                        REPLACE(p_database_name, "`", "``"),
                        "`."
                    )
                ),
                "`",
                REPLACE(p_table_name, "`", "``"),
                "`"
            " LIMIT 0"
        ")"
    )
    ;

    PREPARE _sql_statement FROM @test_select_sql_793441
    ;
    SET @test_select_sql_793441 = NULL
    ;
    EXECUTE _sql_statement
    ;
    DEALLOCATE PREPARE _sql_statement
    ;

    SET p_does_table_exist = 1
    ;
END
$$

DELIMITER ;
sam-6174
  • 3,104
  • 1
  • 33
  • 34
0

This has been my 'go-to' EXISTS procedure that checks both temp and normal tables. This procedure works in MySQL version 5.6 and above. The @DEBUG parameter is optional. The default schema is assumed, but can be concatenated to the table in the @s statement.

drop procedure if exists `prcDoesTableExist`;
delimiter #
CREATE PROCEDURE `prcDoesTableExist`(IN pin_Table varchar(100), OUT pout_TableExists BOOL)
BEGIN
    DECLARE `boolTableExists` TINYINT(1) DEFAULT 1;
    DECLARE CONTINUE HANDLER FOR 1243, SQLSTATE VALUE '42S02' SET `boolTableExists` := 0;
        SET @s = concat('SELECT null FROM `', pin_Table, '` LIMIT 0 INTO @resultNm');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;
    set pout_TableExists = `boolTableExists`; -- Set output variable
    IF @DEBUG then
        select IF(`boolTableExists`
            , CONCAT('TABLE `', pin_Table, '` exists: ', pout_TableExists)
            , CONCAT('TABLE `', pin_Table, '` does not exist: ', pout_TableExists)
        ) as result;
    END IF;
END #
delimiter ;

Here is the example call statement with @debug on:

set @DEBUG = true;
call prcDoesTableExist('tempTable', @tblExists);
select @tblExists as '@tblExists';

The variable @tblExists returns a boolean.

MAbraham1
  • 1,717
  • 4
  • 28
  • 45
0

Before creating a TABLE, it is always advisable to check whether the table exists in SQL Server database or not.

USE [DB_NAME]
GO
IF OBJECT_ID('table_name', 'U') IS NOT NULL
BEGIN
PRINT 'Table exists.'
END
ELSE
BEGIN
PRINT 'Table does not exist.'
END

Alternatively Using the sys.Objects to check whether a table exists in SQL Server or not.

USE [DB_NAME]
GO
IF EXISTS(SELECT 1 FROM sys.Objects
WHERE Object_id = OBJECT_ID(N'table_name')
AND Type = N'U')
BEGIN
PRINT 'Table exists.'
END
ELSE
BEGIN
PRINT 'Table does not exist.'
END
MD SHAYON
  • 7,001
  • 45
  • 38