Überprüfen Sie, ob eine Tabelle vorhanden ist, ohne "Auswählen aus" zu verwenden.

176

Gibt es eine Möglichkeit zu überprüfen, ob eine Tabelle vorhanden ist, ohne Werte daraus auszuwählen und zu überprüfen?

Das heißt, ich weiß, dass ich SELECT testcol FROM testtabledie Anzahl der zurückgegebenen Felder überprüfen kann , aber es scheint, dass es einen direkteren / eleganteren Weg geben muss, dies zu tun.

Ben
quelle
Besuchen Sie stackoverflow.com/a/167680/12495091 für die Antwort !!!!!!!!!
Saurabh Chopra
@SaurabhChopra Das ist für SQL Server, hier wird nach MySql gefragt.
Alejandro

Antworten:

323

Wenn Sie korrekt sein möchten, verwenden Sie INFORMATION_SCHEMA .

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

Alternativ können Sie verwenden SHOW TABLES

SHOW TABLES LIKE 'yourtable';

Wenn die Ergebnismenge eine Zeile enthält, ist eine Tabelle vorhanden.

Sergio Tulentsev
quelle
3
Ja, das funktioniert gut und ist elegant, verwendet aber immer noch SELECT...FROMSyntax ... Ich habe nach etwas gesucht wieEXISTS testtable
Ben
9
Die Art und Weise, wie Marc und ich es angegeben haben, ist die richtige. Es gibt keine Typanweisung 'existiert' MySql. 'Exists' in MySql ist eine Klausel, die eine Operation wie SELECT, UPDATE oder DELETE erfordert.
Google
@Steve Die dritte Option ist nicht portabel.
ta.speot.is
1
@SergioTulentsev Unabhängig vom Tag bevorzuge ich den tragbaren Weg gegenüber dem proprietären Weg.
ta.speot.is
1
@Filype Dies ist kein wirkliches Problem, da er nur prüft, ob die Abfrage erfolgreich war oder nicht. In dem Fall, in dem die Tabelle keine Zeilen enthält, ist die Abfrage weiterhin erfolgreich, nur mit einer leeren Ergebnismenge.
Bill Dami
66
SELECT count(*)
FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = 'your_db_name') AND (TABLE_NAME = 'name_of_table')

Wenn Sie eine Zählung ungleich Null erhalten, ist die Tabelle vorhanden.

Marc B.
quelle
2
Ich verstehe wirklich nicht, was hier passiert ist. Ich habe die Antworten überprüft, weil ich es jetzt mache, und es ist wahr, dass Sergio Tulentsevs Antwort früher (1 Minute) war und 3 Lösungen anbot, aber diese ist die effektivste. Warum sollte ich mehr oder etwas anderes auswählen, was ich will? Ich brauche in diesem Fall einen "booleschen" 1/0. Ist die Tabelle vorhanden oder nicht? Ich möchte nicht alles einschränken, ich möchte nichts mögen, ich möchte keine Fehler. Dies sollte die akzeptierte Antwort sein.
Vaso123
1
Beachten Sie, dass dies auf einem TEMPORARY TABLEnicht funktioniert.
Thomas Lobker
27

Ein Leistungsvergleich:

  • MySQL 5.0.77 auf einer Datenbank mit etwa 11.000 Tabellen.
  • Auswählen einer nicht zuletzt verwendeten Tabelle, damit diese nicht zwischengespeichert wird.
  • Durchschnittlich über jeweils 10 Versuche. (Hinweis: Mit verschiedenen Tabellen durchgeführt, um ein Zwischenspeichern zu vermeiden.)

322 ms: show tables like 'table201608';

691 ms: select 1 from table201608 limit 1;

319 ms: SELECT count(*) FROM information_schema.TABLES WHERE (TABLE_SCHEMA = 'mydb') AND (TABLE_NAME = 'table201608');

Beachten Sie, dass wenn Sie dies häufig ausführen - wie bei vielen HTML-Anforderungen in kurzer Zeit - die zweite viel schneller ist, da sie durchschnittlich 200 ms oder schneller zwischengespeichert wird.

Ken Fricklas
quelle
16

Sie können die tablesSystemansicht INFORMATION_SCHEMA abfragen :

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

Wenn keine Zeilen zurückgegeben werden, ist die Tabelle nicht vorhanden.

Google
quelle
9

Nachdem ich alle oben genannten Punkte gelesen habe, bevorzuge ich die folgende Aussage:

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

Es zeigt genau an, was Sie tun möchten, und gibt tatsächlich einen 'Booleschen Wert' zurück.

Stationärer Reisender
quelle
2
Dies sollte die akzeptierte Antwort sein. prägnant und einfach
Dika
Dies gibt keinen Booleschen Wert zurück, sondern eine Ergebnismenge. var_dump:mysqli_result Object ( [current_field] => 0 [field_count] => 1 [lengths] => [num_rows] => 1 [type] => 0 )
camslice
7

Anstatt sich auf Fehler zu verlassen, können Sie abfragen INFORMATION_SCHEMA.TABLES, ob die Tabelle vorhanden ist. Wenn es einen Datensatz gibt, existiert er. Wenn es keine Aufzeichnung gibt, existiert sie nicht.

ta.speot.is
quelle
1
Ahh, jetzt kommen wir näher! Ich werde es versuchen.
Ben
1
@Steve: Es ist immer noch ein SELECT FROM. :-)
Sergio Tulentsev
7

Hier ist eine Tabelle, die kein SELECT * FROM ist

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

Ich habe dies von einem Datenbankprofi erhalten. Folgendes wurde mir gesagt:

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
csukcc
quelle
Am einfachsten und effizientesten.
e2-e4
3

Diese modifizierte Lösung von oben erfordert keine explizite Kenntnis der aktuellen Datenbank. Es ist dann flexibler.

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

Nur um eine zusätzliche Möglichkeit hinzuzufügen, und je nachdem, wofür Sie sie benötigen, können Sie einen Handler für den Fehler er_no_such_table verwenden : 1146 wie folgt :

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 ;
Eracuna
quelle
2

zeige Tabellen wie 'table_name'

Wenn dies Zeilen> 0 zurückgibt, existiert die Tabelle

Stefan
quelle
1

Sie können Folgendes tun:

            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!");
            }
Manish Jain
quelle
1

Wenn man diese Antwort erweitert , könnte man eine Funktion weiter schreiben, die TRUE / FALSE zurückgibt, basierend darauf, ob eine Tabelle existiert oder nicht:

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');
Nae
quelle
1

Diese kompakte Methode gibt 1 zurück, wenn vorhanden 0, wenn nicht vorhanden.

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

Sie können eine MySQL-Funktion eingeben

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 ;

und nenne es

Select ExistTable('my_table');

1 zurückgeben, falls vorhanden 0, falls nicht vorhanden.

MCO
quelle
0

Ich benutze dies in 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;
    }
Raza
quelle
0

Bei den Antworten hier sind einige Probleme zu beachten:

1) INFORMATION_SCHEMA.TABLESenthält keine TEMPORARY-Tabellen.

2) Wenn Sie einen beliebigen SHOWAbfragetyp verwenden, SHOW TABLES LIKE 'test_table'wird die Rückgabe einer Ergebnismenge an den Client erzwungen. Dies ist ein unerwünschtes Verhalten, um zu überprüfen, ob eine Tabelle serverseitig vorhanden ist, und zwar innerhalb einer gespeicherten Prozedur, die auch eine Ergebnismenge zurückgibt.

3) Wie einige Benutzer erwähnt haben, müssen Sie vorsichtig sein, wie Sie verwenden SELECT 1 FROM test_table LIMIT 1 .

Wenn Sie etwas tun wie:

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

Sie erhalten nicht das erwartete Ergebnis, wenn die Tabelle keine Zeilen enthält.

Unten finden Sie eine gespeicherte Prozedur, die für alle Tabellen (auch TEMPORARY) funktioniert.

Es kann verwendet werden wie:

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;

Der Code:

/*
    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 ;
user2426679
quelle
0

Dies war meine EXISTS-Prozedur, mit der sowohl temporäre als auch normale Tabellen überprüft werden. Dieses Verfahren funktioniert in MySQL Version 5.6 und höher. Der Parameter @DEBUG ist optional. Das Standardschema wird angenommen, kann jedoch mit der Tabelle in der @ s-Anweisung verknüpft werden.

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 ;

Hier ist die Beispielaufrufanweisung mit @debug:

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

Die Variable @tblExists gibt einen Booleschen Wert zurück.

MAbraham1
quelle
-1

Keine der Optionen außer SELECT erlaubt keinen Datenbanknamen, wie er in SELECT verwendet wird. Deshalb habe ich Folgendes geschrieben:

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