มีวิธีการตรวจสอบว่าตารางที่มีอยู่โดยไม่ต้องเลือกและตรวจสอบค่าจากมันได้หรือไม่
นั่นคือฉันรู้ว่าฉันสามารถไปSELECT testcol FROM testtable
และตรวจสอบจำนวนของเขตข้อมูลที่ส่งคืน แต่ดูเหมือนว่าจะต้องมีวิธีที่ตรง / หรูหรามากขึ้นในการทำ
มีวิธีการตรวจสอบว่าตารางที่มีอยู่โดยไม่ต้องเลือกและตรวจสอบค่าจากมันได้หรือไม่
นั่นคือฉันรู้ว่าฉันสามารถไปSELECT testcol FROM testtable
และตรวจสอบจำนวนของเขตข้อมูลที่ส่งคืน แต่ดูเหมือนว่าจะต้องมีวิธีที่ตรง / หรูหรามากขึ้นในการทำ
คำตอบ:
หากคุณต้องการที่จะเป็นที่ถูกต้องใช้INFORMATION_SCHEMA
SELECT *
FROM information_schema.tables
WHERE table_schema = 'yourdb'
AND table_name = 'testtable'
LIMIT 1;
หรือคุณสามารถใช้ SHOW TABLES
SHOW TABLES LIKE 'yourtable';
หากมีแถวในชุดผลลัพธ์จะมีตารางอยู่
SELECT...FROM
ไวยากรณ์ ... ฉันกำลังมองหาบางอย่างที่เหมือนกันEXISTS testtable
SELECT count(*)
FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = 'your_db_name') AND (TABLE_NAME = 'name_of_table')
หากคุณได้รับการนับที่ไม่เป็นศูนย์ตารางนั้นจะมีอยู่
TEMPORARY TABLE
นี้ไม่ทำงาน
การเปรียบเทียบประสิทธิภาพ:
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 จำนวนมากในระยะเวลาอันสั้น - ลำดับที่ 2 จะเร็วขึ้นเนื่องจากแคชจะมีค่าเฉลี่ย 200 ms หรือเร็วกว่า
คุณสามารถสอบถามtables
มุมมองระบบINFORMATION_SCHEMA :
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'databasename'
AND table_name = 'testtable';
หากไม่มีการส่งคืนแถวแสดงว่าไม่มีตาราง
หลังจากอ่านทั้งหมดข้างต้นแล้วฉันชอบข้อความต่อไปนี้:
SELECT EXISTS(
SELECT * FROM information_schema.tables
WHERE table_schema = 'db'
AND table_name = 'table'
);
มันบ่งบอกสิ่งที่คุณต้องการจะทำและมันจะส่งกลับ 'บูลีน'
mysqli_result Object ( [current_field] => 0 [field_count] => 1 [lengths] => [num_rows] => 1 [type] => 0 )
แทนที่จะพึ่งพาข้อผิดพลาดคุณสามารถค้นหาINFORMATION_SCHEMA.TABLES
เพื่อดูว่ามีตารางอยู่หรือไม่ หากมีการบันทึกมันอยู่ หากไม่มีบันทึกมันจะไม่มีอยู่จริง
SELECT FROM
ก็ยังคงเป็น :-)
นี่คือตารางที่ไม่ใช่ 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
โซลูชันที่ปรับเปลี่ยนนี้จากด้านบนไม่ต้องการความรู้ที่ชัดเจนเกี่ยวกับฐานข้อมูลปัจจุบัน มันมีความยืดหยุ่นมากกว่า
SELECT count(*) FROM information_schema.TABLES WHERE TABLE_NAME = 'yourtable'
AND TABLE_SCHEMA in (SELECT DATABASE());
เพียงเพิ่มวิธีพิเศษในการทำและขึ้นอยู่กับสิ่งที่คุณต้องการคุณสามารถใช้ตัวจัดการสำหรับข้อผิดพลาดer_no_such_table : 1146 เช่นนี้:
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 ;
แสดงตารางเช่น 'table_name'
ถ้านี่ส่งคืนแถว> 0 ตารางนั้นมีอยู่
คุณสามารถทำสิ่งต่อไปนี้:
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!");
}
การขยายคำตอบนี้สามารถเขียนฟังก์ชั่นเพิ่มเติมที่คืนค่า 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');
วิธีการกระชับนี้ส่งคืน 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 ถ้าไม่มีอยู่
ฉันใช้สิ่งนี้ใน 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;
}
มีหลายประเด็นที่ควรทราบด้วยคำตอบที่นี่:
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);
คุณจะไม่ได้รับผลลัพธ์ที่คาดหวังหากตารางมีศูนย์แถว
ด้านล่างนี้เป็นกระบวนงานที่เก็บไว้ซึ่งจะใช้งานได้กับทุกตาราง (แม้แต่ชั่วคราว)
มันสามารถใช้เช่น:
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 ;
นี่เป็นขั้นตอน 'go-to' 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 ส่งคืนบูลีน
ไม่มีตัวเลือกยกเว้น SELECT ไม่อนุญาตชื่อฐานข้อมูลที่ใช้ใน SELECT ดังนั้นฉันจึงเขียนสิ่งนี้:
SELECT COUNT(*) AS cnt FROM information_schema.TABLES
WHERE CONCAT(table_schema,".",table_name)="db_name.table_name";