检查表是否存在而不使用“select from”

时间:2012-01-12 01:42:27

标签: mysql sql

有没有办法检查一个表是否存在没有选择并检查它的值?

也就是说,我知道我可以去SELECT testcol FROM testtable并查看返回的字段数,但似乎必须有一种更直接/更优雅的方式来实现它。

18 个答案:

答案 0 :(得分:256)

您无需计算任何内容。

SELECT 1 FROM testtable LIMIT 1;

如果没有错误,则表格存在。

或者,如果您想要正确,请使用INFORMATION_SCHEMA

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

或者,您可以使用SHOW TABLES

SHOW TABLES LIKE 'yourtable';

如果结果集中有一行,则表存在。

答案 1 :(得分:59)

SELECT count(*)
FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = 'your_db_name') AND (TABLE_NAME = 'name_of_table')

如果您获得非零计数,则该表存在。

答案 2 :(得分:24)

绩效比较:

  • MySQL 5.0.77,在一个拥有大约11,000个表的数据库上。
  • 选择最近未使用的表格,使其不被缓存。
  • 每次平均超过10次尝试。 (注意:使用不同的表来完成以避免缓存)。

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');

请注意,如果你经常运行这一点 - 比如短时间内的许多HTML请求 - 第二个会更快,因为它将被缓存平均200毫秒或更快。

答案 3 :(得分:15)

您可以查询INFORMATION_SCHEMA tables系统视图:

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

如果没有返回任何行,则该表不存在。

答案 4 :(得分:7)

您可以查询INFORMATION_SCHEMA.TABLES以查看该表是否存在,而不是依赖于错误。如果有记录,则存在。如果没有记录,则不存在。

答案 5 :(得分:7)

这是一个不是SELECT * FROM

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

从数据库专家那里得到这个,这是我被告知的:

select 1 from `tablename`; //avoids a function call
select * from IMFORMATION_SCHEMA.tables where schema = 'db' and table = 'table' // slow. Field names not accurate
SHOW TABLES FROM `db` LIKE 'tablename'; //zero rows = not exist

答案 6 :(得分:2)

显示'table_name'

等表格

如果返回行> 0表存在

答案 7 :(得分:2)

上面修改过的解决方案不需要明确了解当前数据库。这样便更加灵活了。

SELECT count(*) FROM information_schema.TABLES WHERE TABLE_NAME = 'yourtable' 
AND TABLE_SCHEMA in (SELECT DATABASE());

答案 8 :(得分:2)

阅读以上所有内容后,我倾向于以下声明:

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

它确切地指示您要执行的操作,并且实际上返回一个“布尔值”。

答案 9 :(得分:1)

只是添加一个额外的方法来实现它,并且依赖你需要它可以使用handler er_no_such_table错误:1146像这样:< / p>

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 ;

答案 10 :(得分:1)

您可以执行以下操作:

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

答案 11 :(得分:1)

如果存在,此紧凑方法将返回1;如果不存在,则返回0。

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

您可以加入mysql函数

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 ;

并调用它

Select ExistTable('my_table');

如果存在则返回1,如果不存在则返回0。

答案 12 :(得分:0)

我在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;
    }

答案 13 :(得分:0)

扩展此answer,可以进一步编写一个根据表是否存在返回TRUE / FALSE的函数:

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');

答案 14 :(得分:0)

这里的答案有几个问题要注意:

1)INFORMATION_SCHEMA.TABLES 包括临时表。

2)使用任何类型的SHOW查询,即SHOW TABLES LIKE 'test_table',都将强制将结果集返回给客户端,这是从内部检查表是否存在于服务器端的不良行为。存储过程也返回结果集。

3)正如某些用户所提到的,您必须谨慎使用SELECT 1 FROM test_table LIMIT 1

如果您执行以下操作:

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

如果表的行数为零,则不会获得预期的结果。

以下是适用于所有表(甚至是TEMPORARY)的存储过程。

它可以像这样使用:

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;

代码:

/*
    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 ;

答案 15 :(得分:0)

这是我的“执行” EXISTS过程,该过程检查临时表和标准表。此过程适用于MySQL 5.6及更高版本。 @DEBUG参数是可选的。假定使用默认模式,但可以将其连接到@s语句中的表。

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 ;

以下是带有@debug的示例调用语句:

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

变量@tblExists返回一个布尔值。

答案 16 :(得分:0)

如果在 2019 年之后阅读本文,请注意 MySQL 5.7 添加了一个 # Creating the dataframe: df <- data.frame(id=c("A","A","A","B","B","C","D","D","D","D")) library(dplyr) df %>% group_by(id) %>% mutate(helper = ifelse(row_number()==1, 1,0)) # A tibble: 10 x 2 # Groups: id [4] id helper <chr> <dbl> 1 A 1 2 A 0 3 A 0 4 B 1 5 B 0 6 C 1 7 D 1 8 D 0 9 D 0 10 D 0 过程,用于确定表是否存在,包括 TEMPORARY TABLES。

用法: 将@exist 设置为 ''、'BASE TABLE'、'VIEW'、'TEMPORARY' 之一

table_exists

参考:

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

答案 17 :(得分:-1)

SELECT之外的所有选项都不允许SELECT中使用的数据库名称,所以我写了这个:

SELECT COUNT(*) AS cnt FROM information_schema.TABLES 
WHERE CONCAT(table_schema,".",table_name)="db_name.table_name";