MySQL sprawdza, czy tabela istnieje bez zgłaszania wyjątku


123

Jaki jest najlepszy sposób sprawdzenia, czy tabela istnieje w MySQL (najlepiej przez PDO w PHP) bez zgłaszania wyjątku. Nie mam ochoty analizować wyników „POKAŻ TABELE LIKE” i tak dalej. Musi istnieć jakieś logiczne zapytanie?

Odpowiedzi:


199

Nie znam składni PDO dla tego, ale wydaje się to dość proste:

$result = mysql_query("SHOW TABLES LIKE 'myTable'");
$tableExists = mysql_num_rows($result) > 0;

dzięki, całkowicie zapomniałem, że POKAŻ PODOBNE TABELE może być ograniczone tylko do jednego dokładnego stołu
klapsy

53
PDO: $ tableExists = $ db-> query ("POKAŻ TABELE LIKE 'myTable'") -> rowCount ()> 0;
Reactgular

4
mysqli: if ($ db-> query ("SHOW TABLES LIKE 'myTable'") -> num_rows == 0) {// create table}
zPuls3

1
@MathewFoscarini, rowCount () może w tym przypadku nie być wiarygodne, zobacz dokumentację PHP .
datasn.io

4
Nie ma już wsparcia dla mysql_*funkcji, są one oficjalnie przestarzałe , nie są już obsługiwane i zostaną usunięte w przyszłości. Powinieneś zaktualizować swój kod za pomocą PDO lub MySQLi, aby zapewnić funkcjonalność swojego projektu w przyszłości.
TRiG,

39

Jeśli używasz MySQL 5.0 lub nowszego, możesz spróbować:

SELECT COUNT(*)
FROM information_schema.tables 
WHERE table_schema = '[database name]' 
AND table_name = '[table name]';

Wszelkie wyniki wskazują, że tabela istnieje.

Od: http://www.electrictoolbox.com/check-if-mysql-table-exists/


może czegoś mi brakuje, ale dlaczego miałbyś używać tej metody zamiast SHOW TABLES?
nickf

1
@nickf Jest częścią standardu ansi, więc można go przenosić między różnymi rdbms.
troelskn

@nickf: Działa również na bazach danych innych niż MySQL. O ile wiem, obejmuje to PostgreSQL i SQL Server.
Powerlord

zastanawiasz się, czy to jest exploit bezpieczeństwa, możesz wyszukiwać informacje z baz danych, z którymi nie jesteś połączony ...
Talvi Watia

3
Nie ma żadnego zagrożenia bezpieczeństwa - zapytania do bazy danych schemat_informacyjny będą pokazywać tylko tabele, do których podłączony użytkownik ma uprawnienia.
Warren Rumak

8

Używając mysqli stworzyłem następującą funkcję. Zakładając, że masz instancję mysqli o nazwie $ con.

function table_exist($table){
    global $con;
    $table = $con->real_escape_string($table);
    $sql = "show tables like '".$table."'";
    $res = $con->query($sql);
    return ($res->num_rows > 0);
}

Mam nadzieję, że to pomoże.

Ostrzeżenie: jak sugeruje @jcaron, ta funkcja może być podatna na ataki sqlinjection, więc upewnij się, że twój $tablevar jest czysty lub jeszcze lepiej użyj sparametryzowanych zapytań.


Tylko jeśli pozwolisz komuś wypełnić tablicę $ table var, nie każda zmienna wewnątrz instrukcji sql jest niebezpieczna, tylko jeśli otrzymujesz dane z niezaufanych źródeł. Oczywiście jesteś odpowiedzialny za sposób korzystania z funkcji i filtrowania. nie ma potrzeby odrzucania tej odpowiedzi.
Falk

Jeśli opublikujesz taki kod, ktoś skończy używać go w miejscu, w którym dane nie zostały odpowiednio sprawdzone, i skończy z wstrzyknięciem SQL. Po prostu użyj sparametryzowanych żądań, a unikniesz problemów, niezależnie od tego, czy dane zostały sprawdzone, czy nie. Nie ma żadnego powodu, aby tego nie robić, to po prostu zła praktyka.
jcaron

Co powiesz na dodanie real_escape_string?
Falk

Używaj sparametryzowanych zapytań i unikaj horrorów.
jcaron

4

To jest publikowane po prostu, jeśli ktoś przyjdzie szukać tego pytania. Mimo że udzielono na to trochę odpowiedzi. Niektóre odpowiedzi sprawiają, że jest to bardziej skomplikowane, niż powinno.

Dla mysql * użyłem:

if (mysqli_num_rows(
    mysqli_query(
                    $con,"SHOW TABLES LIKE '" . $table . "'")
                ) > 0
        or die ("No table set")
    ){

W PDO użyłem:

if ($con->query(
                   "SHOW TABLES LIKE '" . $table . "'"
               )->rowCount() > 0
        or die("No table set")
   ){

Dzięki temu po prostu wsuwam warunek else do lub. A dla moich potrzeb potrzebuję tylko umrzeć. Chociaż możesz ustawić lub na inne rzeczy. Niektórzy mogą preferować if / else if / else. Oznacza to usunięcie lub dostarczenie if / else if / else.


3

Oto moje rozwiązanie, które preferuję podczas korzystania z procedur składowanych. Niestandardowa funkcja mysql do sprawdzenia, czy tabela istnieje w bieżącej bazie danych.

delimiter $$

CREATE FUNCTION TABLE_EXISTS(_table_name VARCHAR(45))
RETURNS BOOLEAN
DETERMINISTIC READS SQL DATA
BEGIN
    DECLARE _exists  TINYINT(1) DEFAULT 0;

    SELECT COUNT(*) INTO _exists
    FROM information_schema.tables 
    WHERE table_schema =  DATABASE()
    AND table_name =  _table_name;

    RETURN _exists;

END$$

SELECT TABLE_EXISTS('you_table_name') as _exists

2

Ponieważ funkcja „Pokaż tabele” może działać wolno w przypadku większych baz danych, zalecam użycie opcji „OPISUJ” i sprawdzenie, czy w rezultacie otrzymujesz wartość prawda / fałsz

$tableExists = mysqli_query("DESCRIBE `myTable`");

Z tego, co przeczytałem, jeśli „POKAŻ” stanie się nieefektywne, to „schemat_informacyjny” jest bardziej preferowany niż „OPIS”.
Esoterica,

-1
$q = "SHOW TABLES";
$res = mysql_query($q, $con);
if ($res)
while ( $row = mysql_fetch_array($res, MYSQL_ASSOC) )
{
    foreach( $row as $key => $value )
    {
        if ( $value = BTABLE )  // BTABLE IS A DEFINED NAME OF TABLE
            echo "exist";
        else
            echo "not exist";
    }
}

2
Dodaj dokładny komentarz do kodu, aby zapewnić najlepszą jakość odpowiedzi. Proste wklejenie kodu niewiele mówi autorowi pytania.
Jakub Matczak

5
To jest naprawdę okropne. Więc jeśli jest 50 000 tabel, załadowałbyś wszystkie tabele i przeszedł pętlę, aby sprawdzić, czy istnieje właściwa tabela?
Rohit Chopra

-1

Framework Zend

public function verifyTablesExists($tablesName)
    {
        $db = $this->getDefaultAdapter();
        $config_db = $db->getConfig();

        $sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{$config_db['dbname']}'  AND table_name = '{$tablesName}'";

        $result = $db->fetchRow($sql);
        return $result;

    }


-9

Dlaczego tak trudno to zrozumieć?

function table_exist($table){ 
    $pTableExist = mysql_query("show tables like '".$table."'");
    if ($rTableExist = mysql_fetch_array($pTableExist)) {
        return "Yes";
    }else{
        return "No";
    }
} 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.