Ich möchte in allen Feldern aus allen Tabellen einer MySQL-Datenbank nach einer bestimmten Zeichenfolge suchen, möglicherweise unter Verwendung der folgenden Syntax:
SELECT * FROM * WHERE * LIKE '%stuff%'
Ist es möglich so etwas zu tun?
Ich möchte in allen Feldern aus allen Tabellen einer MySQL-Datenbank nach einer bestimmten Zeichenfolge suchen, möglicherweise unter Verwendung der folgenden Syntax:
SELECT * FROM * WHERE * LIKE '%stuff%'
Ist es möglich so etwas zu tun?
Antworten:
Sie können einen Blick in das information_schema
Schema werfen. Es enthält eine Liste aller Tabellen und aller Felder in einer Tabelle. Sie können dann Abfragen mit den Informationen ausführen, die Sie aus dieser Tabelle erhalten haben.
Die beteiligten Tabellen sind SCHEMATA, TABLES und COLUMNS. Es gibt Fremdschlüssel, mit denen Sie genau festlegen können, wie die Tabellen in einem Schema erstellt werden.
information_schema
ist eine Datenbank, keine Tabelle. Eine Klarstellung, in welcher Tabelle gesucht werden soll, information_schema
wäre gut!
Sie können eine SQLDump
der Datenbanken (und ihrer Daten) ausführen und dann diese Datei durchsuchen.
mysqldump -T
dass zwei Dateien pro Tabelle in einem bestimmten Verzeichnis erstellt werden. Ich dann grep <search> *
in das Verzeichnis, und was zurückgegeben wird, ist die Datei tablename.txt oder .sql. Die txt-Datei enthält die Daten für die Tabelle (durch Tabulatoren getrennt, in CSV umbenennen, um sie in Excel zu öffnen), und die SQL enthält die Tabellendefinition in, Sie haben es erraten: SQL. Auf diese Weise durchsuchen Sie alles und können ganz einfach eingrenzen, wo sich Ihre Daten befinden. In bestimmten Umgebungen kann es jedoch schwierig sein, diese Methode zum Laufen zu bringen. Stapelüberlauf ist hier sehr hilfreich.
Wenn Sie phpMyAdmin installiert haben, verwenden Sie die Suchfunktion.
Ich habe dies für bis zu 250 Tabellen- / 10-GB-Datenbanken (auf einem schnellen Server) verwendet und die Antwortzeit ist geradezu erstaunlich.
PHP-Funktion:
function searchAllDB($search){
global $mysqli;
$out = "";
$sql = "show tables";
$rs = $mysqli->query($sql);
if($rs->num_rows > 0){
while($r = $rs->fetch_array()){
$table = $r[0];
$out .= $table.";";
$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()){
$column = $r2[0];
$sql_search_fields[] = $column." like('%".$search."%')";
}
$rs2->close();
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs3 = $mysqli->query($sql_search);
$out .= $rs3->num_rows."\n";
if($rs3->num_rows > 0){
$rs3->close();
}
}
$rs->close();
}
return $out;
}
$mysqli
so ein:$mysqli = new mysqli('localhost', 'root', 'hunter2', 'my_database');
$colum
mit , "`$colum`"
so dass Felder , die reservierte Wörter sind , werden nicht zu Problemen führen
Sie können dieses Projekt verwenden: http://code.google.com/p/anywhereindb
Dadurch werden alle Daten in allen Tabellen durchsucht.
Wenn Sie stored procedures
die Pest meiden oder mysql_dump
aufgrund von Berechtigungen nicht in der Lage sind, dies zu tun, oder wenn Sie auf andere Gründe stoßen.
Ich würde einen dreistufigen Ansatz wie diesen vorschlagen:
1) Wenn diese Abfrage eine Reihe von Abfragen als Ergebnismenge erstellt.
# =================
# VAR/CHAR SEARCH
# =================
# BE ADVISED USE ANY OF THESE WITH CAUTION
# DON'T RUN ON YOUR PRODUCTION SERVER
# ** USE AN ALTERNATE BACKUP **
SELECT
CONCAT('SELECT * FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME,
' WHERE ', A.COLUMN_NAME, ' LIKE \'%stuff%\';')
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'
AND
(
A.DATA_TYPE LIKE '%text%'
OR
A.DATA_TYPE LIKE '%char%'
)
;
.
# =================
# NUMBER SEARCH
# =================
# BE ADVISED USE WITH CAUTION
SELECT
CONCAT('SELECT * FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME,
' WHERE ', A.COLUMN_NAME, ' IN (\'%1234567890%\');')
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'
AND A.DATA_TYPE IN ('bigint','int','smallint','tinyint','decimal','double')
;
.
# =================
# BLOB SEARCH
# =================
# BE ADVISED THIS IS CAN END HORRIFICALLY IF YOU DONT KNOW WHAT YOU ARE DOING
# YOU SHOULD KNOW IF YOU HAVE FULL TEXT INDEX ON OR NOT
# MISUSE AND YOU COULD CRASH A LARGE SERVER
SELECT
CONCAT('SELECT CONVERT(',A.COLUMN_NAME, ' USING utf8) FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME,
' WHERE CONVERT(',A.COLUMN_NAME, ' USING utf8) IN (\'%someText%\');')
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'
AND A.DATA_TYPE LIKE '%blob%'
;
Die Ergebnisse sollten folgendermaßen aussehen:
2) Sie können dann einfach Right Click
und verwendenCopy Row (tab-separated)
3) Einfügen führt zu einem neuen Abfragefenster und wird nach Herzenslust ausgeführt.
Detail: Ich schließe Systemschemata aus, die normalerweise nicht in Ihrer Workbench angezeigt werden, es sei denn, Sie haben die Option Show Metadata and Internal Schemas
aktiviert.
Ich habe dies getan, um bei Bedarf einen schnellen Weg zu ANALYZE
einem gesamten HOST oder einer gesamten Datenbank bereitzustellen oder um OPTIMIZE
Anweisungen zur Unterstützung von Leistungsverbesserungen auszuführen .
Ich bin mir sicher, dass es verschiedene Möglichkeiten gibt, dies zu tun, aber hier ist, was für mich funktioniert:
-- ========================================== DYNAMICALLY FIND TABLES AND CREATE A LIST OF QUERIES IN THE RESULTS TO ANALYZE THEM
SELECT CONCAT('ANALYZE TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbname';
-- ========================================== DYNAMICALLY FIND TABLES AND CREATE A LIST OF QUERIES IN THE RESULTS TO OPTIMIZE THEM
SELECT CONCAT('OPTIMIZE TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbname';
Getestet auf MySQL Version: 5.6.23
WARNUNG: Führen Sie dies nicht aus, wenn:
- Sie haben Bedenken, Tabellensperren zu verursachen (behalten Sie Ihre Client-Verbindungen im Auge).
Sie sind sich nicht sicher, was Sie tun.
Sie versuchen, Ihren DBA zu verärgern. (Sie können haben die Menschen an Ihrem Schreibtisch mit der Schnelligkeit .)
Prost, Jay; -]
Ich habe auch meinen eigenen MySQL-Crawler erstellt, um eine WordPress-Konfiguration zu durchsuchen, konnte sie nicht sowohl in der Benutzeroberfläche als auch in der Datenbank finden, und Datenbank-Dumps waren zu schwer und unlesbar. Ich muss sagen, ich kann jetzt nicht darauf verzichten.
Es funktioniert wie das von @Olivier, verwaltet jedoch exotische Datenbank- / Tabellennamen und ist LIKE-Joker-sicher.
<?php
$database = 'database';
$criteria = '*iemblo'; // you can use * and ? as jokers
$dbh = new PDO("mysql:host=127.0.0.1;dbname={$database};charset=utf8", 'root', '');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$tables = $dbh->query("SHOW TABLES");
while (($table = $tables->fetch(PDO::FETCH_NUM)) !== false)
{
$fields = $dbh->prepare("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?");
$fields->execute(array ($database, $table[0]));
$ors = array ();
while (($field = $fields->fetch(PDO::FETCH_NUM)) !== false)
{
$ors[] = str_replace("`", "``", $field[0]) . " LIKE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(:search, '\\\\', '\\\\\\\\'), '%', '\\%'), '_', '\\_'), '*', '%'), '?', '_')";
}
$request = 'SELECT * FROM ';
$request .= str_replace("`", "``", $table[0]);
$request .= ' WHERE ';
$request .= implode(' OR ', $ors);
$rows = $dbh->prepare($request);
$rows->execute(array ('search' => $criteria));
$count = $rows->rowCount();
if ($count == 0)
{
continue;
}
$str = "Table '{$table[0]}' contains {$count} rows matching '{$criteria}'.";
echo str_repeat('-', strlen($str)), PHP_EOL;
echo $str, PHP_EOL;
echo str_repeat('-', strlen($str)), PHP_EOL;
$counter = 1;
while (($row = $rows->fetch(PDO::FETCH_ASSOC)) !== false)
{
$col = 0;
$title = "Row #{$counter}:";
echo $title;
foreach ($row as $column => $value)
{
echo
(($col++ > 0) ? str_repeat(' ', strlen($title) + 1) : ' '),
$column, ': ',
trim(preg_replace('!\s+!', ' ', str_replace(array ("\r", "\t", "\n"), array ("", "", " "), $value))),
PHP_EOL;
}
echo PHP_EOL;
$counter++;
}
}
Das Ausführen dieses Skripts könnte Folgendes ausgeben:
---------------------------------------------------
Table 'customers' contains 1 rows matching '*iemblo'.
---------------------------------------------------
Row #1: email_client: my@email.com
numero_client_compta: C05135
nom_client: Tiemblo
adresse_facturation_1: 151, My Street
adresse_facturation_2:
ville_facturation: Nantes
code_postal_facturation: 44300
pays_facturation: FR
numero_tva_client:
zone_geographique: UE
prenom_client: Alain
commentaires:
nom_societe:
email_facturation: my@email.com
Dies ist die einfachste Abfrage, um alle Spalten und Tabellen abzurufen
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
Alle Tabellen oder Tabellen mit einer bestimmten Zeichenfolge im Namen können über die Registerkarte Suchen in phpMyAdmin durchsucht werden.
Habe eine nette Frage ... \ ^. ^ /
Mit MySQL Workbench ist es einfach, mehrere Tabellen auszuwählen und in all diesen Tabellen der DB nach Text zu suchen ;-)
Obwohl diese Frage alt ist, erfahren Sie hier, wie Sie dies tun können, wenn Sie die MySQL-Workbench 6.3 verwenden. (Höchstwahrscheinlich funktioniert es auch für andere Versionen)
Klicken Sie mit der rechten Maustaste auf Ihr Schema und "Tabellendaten durchsuchen", geben Sie Ihren Wert ein und klicken Sie auf "Suche starten". Das ist es.
Hier ist meine Lösung dafür
DROP PROCEDURE IF EXISTS findAll;
CREATE PROCEDURE `findAll`( IN `tableName` VARCHAR( 28 ) , IN `search` TEXT )
BEGIN
DECLARE finished INT DEFAULT FALSE ;
DECLARE columnName VARCHAR ( 28 ) ;
DECLARE stmtFields TEXT ;
DECLARE columnNames CURSOR FOR
SELECT DISTINCT `COLUMN_NAME` FROM `information_schema`.`COLUMNS`
WHERE `TABLE_NAME` = tableName ORDER BY `ORDINAL_POSITION` ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = TRUE;
SET stmtFields = '' ;
OPEN columnNames ;
readColumns: LOOP
FETCH columnNames INTO columnName ;
IF finished THEN
LEAVE readColumns ;
END IF;
SET stmtFields = CONCAT(
stmtFields , IF ( LENGTH( stmtFields ) > 0 , ' OR' , '' ) ,
' `', tableName ,'`.`' , columnName , '` REGEXP "' , search , '"'
) ;
END LOOP;
SET @stmtQuery := CONCAT ( 'SELECT * FROM `' , tableName , '` WHERE ' , stmtFields ) ;
PREPARE stmt FROM @stmtQuery ;
EXECUTE stmt ;
CLOSE columnNames ;
END;
CALL findAll('tbl_test','abb')
Fehler: # 1267 - Unzulässige Mischung von Kollatierungen (utf8_general_ci, IMPLICIT) und (utf8_unicode_ci, IMPLICIT) für Operation '=' Können Sie das Problem beheben? Vielen Dank!
Dies ist der einfache Weg, den ich kenne. Wählen Sie Ihre Datenbank in PHPMyAdmin aus, gehen Sie zur Registerkarte "Suchen" und schreiben Sie, was Sie suchen möchten und wo Sie suchen werden. Wählen Sie alle Tabellen aus, wenn Sie die Wörter aus allen Tabellen suchen möchten. Dann "GO" und schauen Sie sich das Ergebnis an.
Ich benutze HeidiSQL ist ein nützliches und zuverlässiges Tool für Webentwickler, die den beliebten MySQL-Server verwenden.
In HeidiSQL können Sie Shift + Strg + F drücken und in allen Tabellen finden Sie Text auf dem Server. Diese Option ist sehr nützlich.
Du könntest benutzen
SHOW TABLES;
Dann holen Sie sich die Spalten in diesen Tabellen (in einer Schleife) mit
SHOW COLUMNS FROM table;
und dann mit diesen Informationen viele, viele Abfragen erstellen, die Sie bei Bedarf auch UNION können.
Dies ist jedoch extrem belastend für die Datenbank. Insbesondere, wenn Sie eine LIKE-Suche durchführen.
SHOW TABLES FROM <db_name>
ist genauer
Diese Lösung
a) ist nur MySQL, es wird keine andere Sprache benötigt, und
b) gibt SQL-Ergebnisse zurück, die zur Verarbeitung bereit sind!
#Search multiple database tables and/or columns
#Version 0.1 - JK 2014-01
#USAGE: 1. set the search term @search, 2. set the scope by adapting the WHERE clause of the `information_schema`.`columns` query
#NOTE: This is a usage example and might be advanced by setting the scope through a variable, putting it all in a function, and so on...
#define the search term here (using rules for the LIKE command, e.g % as a wildcard)
SET @search = '%needle%';
#settings
SET SESSION group_concat_max_len := @@max_allowed_packet;
#ini variable
SET @sql = NULL;
#query for prepared statement
SELECT
GROUP_CONCAT("SELECT '",`TABLE_NAME`,"' AS `table`, '",`COLUMN_NAME`,"' AS `column`, `",`COLUMN_NAME`,"` AS `value` FROM `",TABLE_NAME,"` WHERE `",COLUMN_NAME,"` LIKE '",@search,"'" SEPARATOR "\nUNION\n") AS col
INTO @sql
FROM `information_schema`.`columns`
WHERE TABLE_NAME IN
(
SELECT TABLE_NAME FROM `information_schema`.`columns`
WHERE
TABLE_SCHEMA IN ("my_database")
&& TABLE_NAME IN ("my_table1", "my_table2") || TABLE_NAME LIKE "my_prefix_%"
);
#prepare and execute the statement
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
#1243 - Unknown prepared statement handler (stmt) given to EXECUTE
erhalte eine Fehlermeldung, wenn ich Ihre Abfrage in Phpmyadmin für die Suche in der gesamten Datenbank ausführe
Ich habe die PHP-Antwort von Olivier ein wenig geändert, um:
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;
}
Ich habe auf einer früheren Antwort aufgebaut und habe diese, einige zusätzliche Auffüllungen, nur um die gesamte Ausgabe bequem verbinden zu können:
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, fügen es dann ein und führen das Ergebnis aus (keine Bearbeitung). Es werden alle Tabellennamen und Spalten angezeigt, in denen der Wert verwendet wird.
WHERE NOT A.TABLE_SCHEMA IN ('mysql', 'innodb', 'performance_schema', 'information_schema')
oder noch besser, führen Sie es aus, überprüfen Sie die verwendeten Schemas und legen Sie das verwendete Schema im where fest, anstatt alle anderen auszuschließen.
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>";
Ich habe dies mit HeidiSQL gemacht. Es ist nicht leicht zu finden, aber durch Drücken von Strg + Umschalt + F wird der Dialog "Tabellenwerkzeuge" angezeigt. Wählen Sie dann aus, was Sie suchen möchten (vollständige Datenbank zu einer einzelnen Tabelle), geben Sie den Wert "Zu suchender Text" ein und klicken Sie auf "Suchen". Ich fand es überraschend schnell (870 MB DB in weniger als einer Minute)
Ich habe Union verwendet, um Abfragen zu verknüpfen. Ich weiß nicht, ob es der effizienteste Weg ist, aber es funktioniert.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
Es gibt eine schöne Bibliothek zum Lesen aller Tabellen, Ridona
$database = new ridona\Database('mysql:dbname=database_name;host=127.0.0.1', 'db_user','db_pass');
foreach ($database->tables()->by_entire() as $row) {
....do
}
Ich weiß nicht, ob dies nur in den letzten Versionen der Fall ist, aber wenn Sie mit der rechten Maustaste auf die Tables
Option im Bereich klicken Navigator
, wird eine Option mit dem Namen angezeigt Search Table Data
. Dies öffnet ein Suchfeld, in das Sie die Suchzeichenfolge eingeben und auf Suchen klicken.
Sie müssen die Tabelle, in der Sie suchen möchten, im linken Bereich auswählen. Wenn Sie jedoch die Umschalttaste gedrückt halten und 10 Tabellen gleichzeitig auswählen, kann MySql dies verarbeiten und Ergebnisse in Sekunden zurückgeben.
Für alle, die nach besseren Optionen suchen! :) :)