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?

clops
źródło

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;
nickf
źródło
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/

Michael Todd
źródło
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ń.

Falk
źródło
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.

Esoterica
źródło
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
erandac
źródło
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`");
Marcina Lisickiego
źródło
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";
    }
}
Namkeen Butter
źródło
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;

    }
gilcierweb
źródło
-1

Jeśli powodem chęci wykonania tego jest warunkowe utworzenie tabeli, wówczas opcja „UTWÓRZ TABELĘ, JEŚLI NIE ISTNIEJE” wydaje się idealna do tego zadania. Dopóki tego nie odkryłem, stosowałem powyższą metodę „DESCRIBE”. Więcej informacji tutaj: MySQL "UTWÓRZ TABELĘ, JEŚLI NIE ISTNIEJE" -> Błąd 1050

Robin Andrews
źródło
-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";
    }
} 
Hamed
źródło