361 Stimmen

Text in Feldern in jeder Tabelle einer MySQL-Datenbank suchen

Ich möchte in allen Feldern aus allen Tabellen einer MySQL-Datenbank eine gegebene Zeichenfolge suchen, möglicherweise mit Syntax wie:

SELECT * FROM * WHERE * LIKE '%stuff%'

Ist es möglich, so etwas zu tun?

3voto

Ólafur Waage Punkte 66497

Sie könnten verwenden

SHOW TABLES;

Holen Sie dann die Spalten in diesen Tabellen (in einer Schleife) mit

SHOW COLUMNS FROM table;

und dann mit diesen Informationen viele viele Abfragen erstellen, die Sie auch UNION, wenn Sie benötigen.

Dies belastet jedoch die Datenbank sehr stark. Vor allem, wenn Sie eine LIKE-Suche durchführen.

2voto

Jim Björklund Punkte 93

Ich habe auf einer früheren Antwort aufgebaut und habe dies, einige zusätzliche Polsterung, nur um in der Lage sein, bequem zu verbinden alle die Ausgabe:

SELECT 
CONCAT('SELECT ''',A.TABLE_NAME, '-' ,A.COLUMN_NAME,''' FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME, 
       ' WHERE ', A.COLUMN_NAME, ' LIKE \'%Value%\' UNION')
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE 
        A.TABLE_SCHEMA != 'mysql' 
AND     A.TABLE_SCHEMA != 'innodb' 
AND     A.TABLE_SCHEMA != 'performance_schema' 
AND     A.TABLE_SCHEMA != 'information_schema'
UNION SELECT 'SELECT '''

-- for exact match use: A.COLUMN_NAME, ' LIKE \'Value\' instead

Zuerst führen Sie dies aus, dann fügen Sie das Ergebnis ein und führen es aus (keine Bearbeitung) und es werden alle Tabellennamen und Spalten angezeigt, in denen der Wert verwendet wird.

2voto

TagFolks Punkte 236

Auch wenn der folgende Vorschlag nicht als endgültige Lösung angesehen werden sollte, können Sie das Ziel erreichen, indem Sie etwas in dieser Art und Weise tun:

SET SESSION group_concat_max_len = 1000000;
SET @search = 'Text_To_Search';

DROP table IF EXISTS table1;
CREATE TEMPORARY TABLE table1 AS 
(SELECT 
    CONCAT('SELECT \'',TABLE_NAME,'\' as \'table_name\',\'',COLUMN_NAME,'\' as \'column_name\',CONVERT(count(*),char) as \'matches\' FROM `',
    TABLE_NAME,'` where `',COLUMN_NAME,'` like \'%',@search,'%\' UNION ') as 'query'
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_name' limit 1000000);

set @query = (SELECT GROUP_CONCAT(t1.`query` SEPARATOR '') as 'final_query' from table1 t1 limit 1);
set @query = (SELECT SUBSTRING(@query, 1, length(@query) - 7));

PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Bitte bedenken Sie das:

  1. Optionen: Gruppe_Katalog_max_len y Grenze 1000000 werden nicht immer benötigt, dies hängt von Ihrer Server/IDE-Konfiguration ab. Für alle Fälle habe ich sie hinzugefügt.

  2. Nach der Ausführung dieses Befehls erhalten Sie eine 3-spaltige Antwort: [tabellen_name], [spalten_name], [übereinstimmungen]

  3. Die Spalte "Treffer" gibt die Anzahl der Vorkommen in der angegebenen Tabelle/Spalte an.

  4. Diese Abfrage ist sehr schnell.

DISCLAIMER: Das wären wir

2voto

Flion Punkte 9646

Ich habe die PHP-Antwort von Olivier ein wenig geändert:

  • die Ergebnisse ausgeben, in denen die Zeichenfolge gefunden wurde
  • Tabellen ohne Ergebnisse weglassen
  • auch die Ausgabe anzeigen, wenn die Spaltennamen mit der Sucheingabe übereinstimmen
  • Gesamtzahl der Ergebnisse anzeigen

    function searchAllDB($search){
        global $mysqli;
    
        $out = "";
        $total = 0;
        $sql = "SHOW TABLES";
        $rs = $mysqli->query($sql);
        if($rs->num_rows > 0){
            while($r = $rs->fetch_array()){
                $table = $r[0];
                $sql_search = "select * from ".$table." where ";
                $sql_search_fields = Array();
                $sql2 = "SHOW COLUMNS FROM ".$table;
                $rs2 = $mysqli->query($sql2);
                if($rs2->num_rows > 0){
                    while($r2 = $rs2->fetch_array()){
                        $colum = $r2[0];
                        $sql_search_fields[] = $colum." like('%".$search."%')";
                        if(strpos($colum,$search))
                        {
                            echo "FIELD NAME: ".$colum."\n";
                        }
                    }
                    $rs2->close();
                }
                $sql_search .= implode(" OR ", $sql_search_fields);
                $rs3 = $mysqli->query($sql_search);
                if($rs3 && $rs3->num_rows > 0)
                {
                    $out .= $table.": ".$rs3->num_rows."\n";
                    if($rs3->num_rows > 0){
                        $total += $rs3->num_rows;
                        $out.= print_r($rs3->fetch_all(),1);
                        $rs3->close();
                    }
                }
            }
            $out .= "\n\nTotal results:".$total;
            $rs->close();
        }
        return $out;
    }

1voto

Trevor Punkte 33

Ich habe das zum Laufen gebracht. Sie müssen nur die Variablen ändern

$query ="SELECT `column_name` FROM `information_schema`.`columns` WHERE `table_schema`='" . $_SESSION['db'] . "' AND `table_name`='" . $table . "' ";
$stmt = $dbh->prepare($query);
$stmt->execute(); 
$columns = $stmt->fetchAll(PDO::FETCH_ASSOC);       

$query="SELECT name FROM `" . $database . "`.`" . $table . "` WHERE ( ";
foreach ( $columns as $column ) {
    $query .=" CONVERT( `" . $column['column_name'] . "` USING utf8 ) LIKE '%" . $search . "%' OR ";
}
$query = substr($query, 0, -3);
$query .= ")";

echo $query . "<br>";
$stmt=$dbh->prepare($query);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "<pre>";
print_r ($results );
echo "</pre>";

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X