有没有一种方法来检查表是否存在,而不选择和检查它的值?
也就是说,我知道我可以去SELECT testcol FROM testtable并检查返回字段的计数,但似乎必须有一个更直接/优雅的方式来做到这一点。
有没有一种方法来检查表是否存在,而不选择和检查它的值?
也就是说,我知道我可以去SELECT testcol FROM testtable并检查返回字段的计数,但似乎必须有一个更直接/优雅的方式来做到这一点。
当前回答
您可以查询INFORMATION_SCHEMA,而不是依赖于错误。TABLES查看表是否存在。如果有记录,那就是存在的。如果没有记录,它就不存在。
其他回答
您可以查询INFORMATION_SCHEMA,而不是依赖于错误。TABLES查看表是否存在。如果有记录,那就是存在的。如果没有记录,它就不存在。
下面是一个不是SELECT * FROM的表
SHOW TABLES FROM `db` LIKE 'tablename'; //zero rows = not exist
这是从一个数据库专家那里得到的,这是我被告知的:
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
上述修改后的解决方案不需要明确了解当前数据库。这样就更灵活了。
SELECT count(*) FROM information_schema.TABLES WHERE TABLE_NAME = 'yourtable'
AND TABLE_SCHEMA in (SELECT DATABASE());
显示像'table_name'这样的表
如果返回行> 0,则表存在
这里的答案有几个问题需要注意:
1) INFORMATION_SCHEMA。TABLES不包括TEMPORARY表。
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 ;