web-dev-qa-db-ja.com

特定のテーブル名がデータベースに存在するかどうかを確認するにはどうすればよいですか?

私がやりたいのは、テーブルが存在するかどうかを確認することだけで、それを理解することができません。

私はもう試した:

_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";
    }
}
_

また、反復可能なJoomlaテーブル名の配列を取得しようとしました。

_Array('table1','table2','table3' etc
_

_SHOW TABLES_でこれを行うことができますが、これにより、それぞれ1つのエントリを持つ配列の大きな配列が生成されます。


私が使用した解決策:

最後に私がやったことを含めています。どちらの回答も役に立ちました。

テーブルの配列を取得するためにこれを行いました:

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

次に、in_array()を使用して、探していたテーブルがそこにあるかどうかを確認しました。

_$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_は、チェックするテーブル名を保持する配列です。

2
user1616338

_SHOW TABLES_を使用すると、loadColumn()で結果を読み込み、テーブル名を値として含む単純な配列を受け取ります。

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

出力:

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

あなたをつまずきそうなのは、あなたの_$tableArray_にプレフィックスがないことです。 FROM句でテーブル名の前に_#___を追加するため、これはクエリで明らかです。結果セットはレンダリングされたプレフィックスとテーブル名を配信するため、入力配列の値は結果セットの値と一致しません。

*重要:ベストプラクティスの問題として、データベースクエリの反復を常に回避するようにしてください。複数のクエリを不必要に実行すると、システムの負荷は言うまでもなく、ページの読み込みが遅くなります。

私は私のローカルホストで成功するために以下をテストしました。これは完全に動的になるように作成しました(データベース名やテーブルのプレフィックスをハードコーディングしないでください)。

結果セットのテーブル名をフィルタリングしたくない場合は、これを使用できます。

_$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;
}
_

それ以外の場合は、クエリロジックを拡張して結果セットをフィルタリングできます。

コード:

_$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
}
_

出力:

_banners table found
content table found
cucumbers table not found
_

より詳細なクエリを使用している理由は、実際にはneedを抽出していないためですeveryデータベースからテーブル名--に存在するものだけが必要です配列。これは、マイクロ最適化ではなく、「直接コーディングの意図」に関するものです(これについては、ベンチマークを行いません)。

_$tableArray_値にはプレフィックスが事前に適合されていないため、INデータにはプレフィックスが付けられます。 SELECTは、foreach()ループでの単純な比較のためにプレフィックスを削除します。


以下は、同じ結果を達成する_SHOW TABLES_を使用した代替アプローチです。

_$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