“Seç” seçeneğini kullanmadan tablonun mevcut olup olmadığını kontrol edin


176

Bir tablonun değer seçip kontrol etmeden bir tablonun var olup olmadığını kontrol etmenin bir yolu var mı?

Yani, SELECT testcol FROM testtablegeri dönüp alanların sayısını kontrol edebileceğimi biliyorum , ama bunu yapmanın daha doğrudan / zarif bir yolu olmalı gibi görünüyor.


Cevap için stackoverflow.com/a/167680/12495091 adresini ziyaret edin !!!!!!!!!
Saurabh Chopra

@SaurabhChopra Bu SQL Server için, bu MySql hakkında soruyor.
Alejandro

Yanıtlar:


323

Doğru olmak istiyorsanız, kullanmak INFORMATION_SCHEMA .

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

Alternatif olarak, SHOW TABLES

SHOW TABLES LIKE 'yourtable';

Sonuç kümesinde bir satır varsa, tablo bulunur.


3
Evet, bu iyi çalışıyor ve zarif ama yine de SELECT...FROMsözdizimi kullanıyor ... Ben bir şey arıyordumEXISTS testtable
Ben

9
Marc ve benim bunu yapma şeklimiz doğru yol. 'Var' türü MySql deyimi yoktur. MySql içindeki 'Var' seçeneği SELECT, UPDATE veya DELETE gibi bir işlem gerektiren bir cümledir.
doogle

@Steve Üçüncü seçenek taşınabilir değildir.
ta.speot.

1
@SergioTulentsev Etikete bakılmaksızın, tescilli şekilde taşınabilir yolu tercih ederim.
ta.speot.

1
@Filype, yalnızca sorgunun başarılı olup olmadığını kontrol ettiği için bu gerçekten bir sorun değil. Tablonun satır içermemesi durumunda, sorgu yalnızca boş bir sonuç kümesiyle başarılı olur.
Bill Dami

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

sıfırdan farklı bir sayı alırsanız, tablo var demektir.


2
Burada olanları gerçekten anlamıyorum. Cevapları kontrol ettim, çünkü şimdi yapıyorum ve Sergio Tulentsevs'in cevabının daha erken olduğu (1 dakika) ve 3 çözüm önerdiği doğru, ancak bu en etkili olanı. Neden istediğimi daha fazla veya başka bir şey seçmeliyim? Bu durumda bir "boolean" 1/0 lazım. Tablo var mı, yok mu? Ben her şeyi sınırlamak istemiyorum, hiçbir şey istemiyorum, herhangi bir hata istemiyorum. Bu kabul edilen cevap olmalı.
vaso123

1
Unutmayın ki TEMPORARY TABLE çalışmadığını unutmayın.
Thomas Lobker

27

Bir performans karşılaştırması:

  • MySQL 5.0.77, yaklaşık 11.000 tablo içeren bir db üzerinde.
  • Son kullanılmayan bir tabloyu önbelleğe alınmayacak şekilde seçme.
  • Ortalama 10 denemeden fazlası. (Not: önbelleğe almayı önlemek için farklı tablolarla yapılır).

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

Kısa bir süre içinde birçok HTML isteğinde olduğu gibi, bunu çok fazla çalıştırıyorsanız, ikincisinin ortalama 200 ms veya daha hızlı önbelleğe alınacağı için çok daha hızlı olacağını unutmayın.


16

BİLGİ_SCHEMA tablessistem görünümünü sorgulayabilirsiniz :

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

Hiçbir satır döndürülmediyse, tablo mevcut değildir.


9

Yukarıdakilerin tümünü okuduktan sonra aşağıdaki ifadeyi tercih ederim:

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

Tam olarak ne yapmak istediğinizi gösterir ve aslında bir 'boolean' döndürür.


2
kabul edilen cevap bu olmalıdır. özlü ve basit
Dika

bu bir Boolean döndürmez, bir sonuç kümesi döndürür. var_dump:mysqli_result Object ( [current_field] => 0 [field_count] => 1 [lengths] => [num_rows] => 1 [type] => 0 )
camslice


7

İşte SELECT * FROM olmayan bir tablo

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

Bu bir veritabanı yanlısı var, işte bana söylendi:

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

En kolay ve verimli.
e2-e4

3

Yukarıdaki bu değiştirilmiş çözüm, geçerli veritabanı hakkında açık bilgi gerektirmez. O zaman daha esnektir.

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

2

Sadece bunu yapmak için ekstra bir yol eklemek ve sizin için neye ihtiyacınız olduğuna bağlı olarak er_no_such_table hatası: 1146 için bir işleyici kullanabilirsiniz :

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 ;

2

'table_name' gibi tabloları göster

eğer bu satır> 0 olursa, tablo var


1

Aşağıdaki gibi bir şey yapabilirsiniz:

            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

Bu cevabı genişleterek , bir tablonun var olup olmamasına bağlı olarak TRUE / FALSE döndüren bir fonksiyon daha yazılabilir:

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

Bu kompakt yöntem, varsa 0 değerini döndürür.

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

Bir mysql işlevi içine koyabilirsiniz

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 ;

ve ara

Select ExistTable('my_table');

Varsa 1 döndürür Varsa 0 döndürür.


0

Ben php kullanın.

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

Buradaki cevaplarla ilgili dikkat edilmesi gereken birkaç sorun var:

1) INFORMATION_SCHEMA.TABLESyapar değil GEÇİCİ tablolar içerir.

2) Herhangi bir tür SHOWsorgu kullanmak , yaniSHOW TABLES LIKE 'test_table' sonuç kümesinin istemciye geri dönmesini zorlar; bu da bir tablonun sunucu tarafında olup olmadığını kontrol etmek için istenmeyen bir davranıştır ve sonuç kümesi döndüren saklı yordamın içinden.

3) Bazı kullanıcıların belirttiği gibi, nasıl kullandığınıza dikkat etmelisiniz SELECT 1 FROM test_table LIMIT 1 .

Gibi bir şey yaparsanız:

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

Tablonun sıfır satırı varsa, beklenen sonucu elde edemezsiniz.

Aşağıda tüm tablolar için çalışacak saklı bir yordam bulunmaktadır (TEMPORARY bile).

Gibi kullanılabilir:

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;

Kod:

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

Bu hem geçici hem de normal tabloları kontrol eden 'go-to' EXISTS prosedürüm oldu. Bu prosedür MySQL sürüm 5.6 ve üstünde çalışır. @DEBUG parametresi isteğe bağlıdır. Varsayılan şema varsayılır, ancak @s deyimindeki tabloyla birleştirilebilir.

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 ;

İşte @debug ile örnek çağrı ifadesi:

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

@TblExists değişkeni bir boole döndürür.


-1

SELECT dışındaki seçeneklerin hiçbiri SELECT'de kullanılan veritabanı adına izin vermez, bu yüzden şunu yazdım:

SELECT COUNT(*) AS cnt FROM information_schema.TABLES 
WHERE CONCAT(table_schema,".",table_name)="db_name.table_name";
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.