it-swarm.com.de

Wie überprüfe ich, ob bestimmte Tabellennamen in einer Datenbank vorhanden sind?

Ich möchte nur überprüfen, ob eine Tabelle vorhanden ist oder nicht, und ich kann es nicht herausfinden.

Ich habe es versucht:

for ($r = 0; $r < count($tableArray); $r++) {
    $db = JFactory::getDbo();
    $query = $db->getQuery(true);
    $query = "select * from `#__".$tableArray[$r]."` LIMIT 1";
    $db->setQuery($query);

    if ($db->setQuery($query) !== False) {
        $results = $db->loadAssocList();
        echo "<br>".$tableArray[$r]."table found";
    } else {
        echo "<br>".$tableArray[$r]."table NOT found";
    }
}

Ich habe auch versucht, eine Reihe von Joomla-Tabellennamen abzurufen, die ich durchlaufen kann.

Array('table1','table2','table3' etc

Ich kann dies mit SHOW TABLES Tun, aber dies erzeugt ein großes Array von Arrays mit jeweils einem Eintrag.


Lösung, die ich verwendet habe:

Ich beziehe ein, was ich am Ende getan habe; Beide Antworten waren hilfreich.

Ich habe dies getan, um das Array der Tabellen zu erhalten:

$db = JFactory::getDbo();
$results = $db->setQuery('SHOW TABLES')->loadColumn();

und dann habe ich in_array() verwendet, um herauszufinden, ob die gesuchte Tabelle vorhanden ist:

$prefix = $db->getPrefix();
for ($r = 0; $r < count($tableArray); $r++) {
    if (in_array($prefix.$tableArray[$r], $results)) {
        echo "<br>Found ".$tableArray[$r];
    }else{
        echo "<br>Missing ".$tableArray[$r];
    }
}

$tableArray Ist das Array, das die zu prüfenden Tabellennamen enthält.

1
user1616338

Bei Verwendung von SHOW TABLES Werden die Ergebnisse mit loadColumn() geladen, um ein einfaches Array mit Tabellennamen als Werten zu erhalten.

print_r(JFactory::getDbo()->setQuery('SHOW TABLES')->loadColumn());

Ausgabe:

Array
(
    [0] => tbl_assets
    [1] => tbl_associations
    [2] => tbl_banner_clients
    [3] => tbl_banner_tracks
    [4] => tbl_banners
...
)
1
Sharky

Was Sie wahrscheinlich auslösen wird, ist, dass Ihr $tableArray Keine Präfixe hat. Dies ist in Ihrer Abfrage offensichtlich, da Sie dem Tabellennamen in der FROM -Klausel #__ Voranstellen. Die Ergebnismenge liefert das gerenderte Präfix mit dem Tabellennamen, sodass Ihre Eingabearraywerte nicht mit den Ergebnismengenwerten übereinstimmen.

* Wichtig: Versuchen Sie immer, iterierte Datenbankabfragen als Best Practice zu vermeiden. Das unnötige Ausführen mehrerer Abfragen führt zu langsamen Seitenladevorgängen, ganz zu schweigen von einer Belastung Ihres Systems.

Ich habe Folgendes getestet, um auf meinem lokalen Host erfolgreich zu sein. Ich habe dies geschrieben, um vollständig dynamisch zu sein (kein festes Codieren des Datenbanknamens oder des Tabellenpräfix).

Wenn Sie die Tabellennamen in der Ergebnismenge nicht filtern möchten, können Sie Folgendes verwenden:

$db = JFactory::getDbo();
$results = $db->setQuery('SHOW TABLES')->loadColumn();

$prefix = $db->getPrefix();
foreach ($tableArray as $t) {
    echo "<br>" , (in_array($prefix.$t, $results) ? "Found " : "Missing ") , $t;
}

Andernfalls können Sie die Ergebnismenge filtern, indem Sie die Abfragelogik erweitern.

Code:

$tableArray = ["banners", "content", "cucumbers"];
try {
    $db = JFactory::getDbo();
    $config = JFactory::getConfig();
    $dbname = $config->get('db');
    $prefix = $db->getPrefix();
    foreach ($tableArray as $t) {
        $q_tablenames[] = $db->q($prefix.$t);  // prefix and quote-wrap for the query
    }
    $query = $db->getQuery(true)
        ->select("SUBSTRING(table_name, 7)")
        ->from("information_schema.tables")
        ->where(["table_schema = " . $db->q($dbname), "table_name IN (" . implode(',', $q_tablenames) . ")"]);
    // echo $query->dump();    // never show to public
    $db->setQuery($query);
    $found = $db->loadColumn();
    foreach ($tableArray as $tablename) {
        echo "<div>$tablename table " , (in_array($tablename, $found) ? "" : "not ") , "found</div>";
    }
} catch (Exception $e) {
    JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error');    // never show actual error to public
}

Ausgabe:

banners table found
content table found
cucumbers table not found

Der Grund, warum ich eine ausführlichere Abfrage verwende, ist, dass ich nicht wirklich muss aus der Datenbank jeden Tabellennamen extrahieren - ich benötige nur die, die in vorhanden sind das Array. Hier geht es eher um "Direct Coding Intentions" als um die Mikrooptimierung (die ich nicht zum Benchmark machen möchte).

Den IN Daten wird ein Präfix vorangestellt, da die $tableArray Werte nicht mit Präfixen versehen sind. Das SELECT schneidet die Präfixe für einfache Vergleiche in der foreach() -Schleife ab.


Hier ist ein alternativer Ansatz mit SHOW TABLES, Der das gleiche Ergebnis erzielt:

$tableArray = ["banners", "content", "cucumbers"];
try {
    $db = JFactory::getDbo();
    $config = JFactory::getConfig();
    $dbname = $config->get('db');
    $prefix = $db->getPrefix();
    foreach ($tableArray as $t) {
        $q_tablenames[] = $db->q($prefix . $t);  // prefix and quote-wrap for the query
    }
    $db->setQuery("SHOW TABLES FROM " . $db->qn($dbname) . " WHERE " . $db->qn("Tables_in_$dbname") . " IN (" . implode(',', $q_tablenames) . ")");
    $found = $db->loadColumn();
    foreach ($tableArray as $tablename) {
        echo "<div>$tablename table " , (in_array($prefix.$tablename, $found) ? "" : "not ") , "found</div>";
    }
} catch (Exception $e) {
    JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error');    // never show to public
}
3
mickmackusa