ตรวจสอบว่ามีตารางอยู่หรือไม่โดยใช้“ เลือกจาก”


176

มีวิธีการตรวจสอบว่าตารางที่มีอยู่โดยไม่ต้องเลือกและตรวจสอบค่าจากมันได้หรือไม่

นั่นคือฉันรู้ว่าฉันสามารถไปSELECT testcol FROM testtableและตรวจสอบจำนวนของเขตข้อมูลที่ส่งคืน แต่ดูเหมือนว่าจะต้องมีวิธีที่ตรง / หรูหรามากขึ้นในการทำ


เยี่ยมชมstackoverflow.com/a/167680/12495091เพื่อรับคำตอบ !!!!!!!!!
Saurabh Chopra

@SaurabhChopra สำหรับ SQL Server นี่คือการถามเกี่ยวกับ MySql
Alejandro

คำตอบ:


323

หากคุณต้องการที่จะเป็นที่ถูกต้องใช้INFORMATION_SCHEMA

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

หรือคุณสามารถใช้ SHOW TABLES

SHOW TABLES LIKE 'yourtable';

หากมีแถวในชุดผลลัพธ์จะมีตารางอยู่


3
ใช่มันใช้งานได้ดีและสง่างาม แต่ก็ยังใช้SELECT...FROMไวยากรณ์ ... ฉันกำลังมองหาบางอย่างที่เหมือนกันEXISTS testtable
Ben

9
วิธีที่ Marc และตัวฉันบอกว่าทำมันเป็นวิธีที่เหมาะสม ไม่มีคำสั่งประเภท 'ที่มีอยู่' MySql 'มีอยู่' ใน MySql เป็นประโยคที่ต้องการการดำเนินการเช่น SELECT, UPDATE หรือ DELETE
doogle

@Steve ตัวเลือกที่สามไม่สามารถพกพาได้
ta.speot.is

1
@SergioTulentsev โดยไม่คำนึงถึงแท็กฉันชอบวิธีพกพาในแบบที่เป็นกรรมสิทธิ์
ta.speot.is

1
@Fypepe นี่ไม่ใช่ปัญหาจริงๆเพราะเขาเพียงตรวจสอบว่าแบบสอบถามประสบความสำเร็จหรือไม่ ในกรณีที่ตารางไม่มีแถวแบบสอบถามจะยังคงประสบความสำเร็จเพียงแค่มีชุดผลลัพธ์ที่ว่างเปล่า
Bill Dami

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

หากคุณได้รับการนับที่ไม่เป็นศูนย์ตารางนั้นจะมีอยู่


2
ฉันไม่เข้าใจว่าเกิดอะไรขึ้นที่นี่ ฉันตรวจสอบคำตอบแล้วเพราะตอนนี้ฉันกำลังทำอยู่และเป็นความจริงที่คำตอบของ Sergio Tulentsevs นั้นเร็วกว่านี้ (1 นาที) และเสนอวิธีแก้ปัญหา 3 ข้อ แต่วิธีนี้มีประสิทธิภาพมากที่สุด ทำไมฉันต้องเลือกอะไรมากกว่านี้หรืออะไรก็ได้ที่ฉันต้องการ ฉันต้องการ "บูลีน" 1/0 ในกรณีนี้ เป็นตารางที่มีอยู่หรือไม่ ฉันไม่ต้องการ จำกัด ทุกอย่างฉันไม่ต้องการอะไรเลยฉันไม่ต้องการข้อผิดพลาดใด ๆ นี่ควรเป็นคำตอบที่ยอมรับได้
vaso123

1
โปรดทราบว่าในสิ่งTEMPORARY TABLEนี้ไม่ทำงาน
โทมัส Lobker

27

การเปรียบเทียบประสิทธิภาพ:

  • 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 จำนวนมากในระยะเวลาอันสั้น - ลำดับที่ 2 จะเร็วขึ้นเนื่องจากแคชจะมีค่าเฉลี่ย 200 ms หรือเร็วกว่า


16

คุณสามารถสอบถามtablesมุมมองระบบINFORMATION_SCHEMA :

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

หากไม่มีการส่งคืนแถวแสดงว่าไม่มีตาราง


9

หลังจากอ่านทั้งหมดข้างต้นแล้วฉันชอบข้อความต่อไปนี้:

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

มันบ่งบอกสิ่งที่คุณต้องการจะทำและมันจะส่งกลับ 'บูลีน'


2
นี่ควรเป็นคำตอบที่ยอมรับได้ กระชับและเรียบง่าย
Dika

สิ่งนี้จะไม่ส่งคืนบูลีน แต่จะส่งคืนชุดผลลัพธ์ var_dump:mysqli_result Object ( [current_field] => 0 [field_count] => 1 [lengths] => [num_rows] => 1 [type] => 0 )
camslice

7

แทนที่จะพึ่งพาข้อผิดพลาดคุณสามารถค้นหาINFORMATION_SCHEMA.TABLESเพื่อดูว่ามีตารางอยู่หรือไม่ หากมีการบันทึกมันอยู่ หากไม่มีบันทึกมันจะไม่มีอยู่จริง


1
อ่าตอนนี้เราใกล้เข้ามาแล้ว! ฉันจะไปลองดู
Ben

1
@ Steve: SELECT FROMก็ยังคงเป็น :-)
Sergio Tulentsev

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

ง่ายและมีประสิทธิภาพ
e2-e4

3

โซลูชันที่ปรับเปลี่ยนนี้จากด้านบนไม่ต้องการความรู้ที่ชัดเจนเกี่ยวกับฐานข้อมูลปัจจุบัน มันมีความยืดหยุ่นมากกว่า

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

2

เพียงเพิ่มวิธีพิเศษในการทำและขึ้นอยู่กับสิ่งที่คุณต้องการคุณสามารถใช้ตัวจัดการสำหรับข้อผิดพลาด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 ;


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

1

การขยายคำตอบนี้สามารถเขียนฟังก์ชั่นเพิ่มเติมที่คืนค่า 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

วิธีการกระชับนี้ส่งคืน 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 ถ้าไม่มีอยู่


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

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

คุณจะไม่ได้รับผลลัพธ์ที่คาดหวังหากตารางมีศูนย์แถว

ด้านล่างนี้เป็นกระบวนงานที่เก็บไว้ซึ่งจะใช้งานได้กับทุกตาราง (แม้แต่ชั่วคราว)

มันสามารถใช้เช่น:

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 ;

0

นี่เป็นขั้นตอน '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 ส่งคืนบูลีน


-1

ไม่มีตัวเลือกยกเว้น SELECT ไม่อนุญาตชื่อฐานข้อมูลที่ใช้ใน SELECT ดังนั้นฉันจึงเขียนสิ่งนี้:

SELECT COUNT(*) AS cnt FROM information_schema.TABLES 
WHERE CONCAT(table_schema,".",table_name)="db_name.table_name";
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.