Voglio cercare in tutti i campi da tutte le tabelle di un database MySQL una data stringa, possibilmente usando la sintassi come:
SELECT * FROM * WHERE * LIKE '%stuff%'
È possibile fare qualcosa del genere?
Voglio cercare in tutti i campi da tutte le tabelle di un database MySQL una data stringa, possibilmente usando la sintassi come:
SELECT * FROM * WHERE * LIKE '%stuff%'
È possibile fare qualcosa del genere?
Risposte:
Puoi sbirciare nello information_schema
schema. Ha un elenco di tutte le tabelle e di tutti i campi che si trovano in una tabella. È quindi possibile eseguire query utilizzando le informazioni ottenute da questa tabella.
Le tabelle coinvolte sono SCHEMATA, TAVOLI e COLONNE. Esistono chiavi esterne in modo da poter costruire esattamente come vengono create le tabelle in uno schema.
information_schema
è un database, non una tabella. Qualche chiarimento su quale tabella cercare all'interno information_schema
sarebbe buono!
È possibile eseguire uno SQLDump
dei database (e i relativi dati), quindi cercare quel file.
mysqldump -T
che crea due file per tabella in una directory specificata. Poi grep <search> *
nella directory, e ciò che viene restituito è il file tablename.txt o .sql. Il file txt contiene i dati per la tabella (delimitato da tabulazione, rinomina in CSV per aprirlo in Excel) e sql contiene la definizione della tabella, avete indovinato: SQL. In questo modo stai cercando tutto ed è facile restringere la posizione dei tuoi dati. Tuttavia, questo metodo può essere abbastanza difficile far funzionare in determinati ambienti. Stack Overflow è molto utile qui.
Se phpMyAdmin è installato, utilizzare la funzione "Cerca".
L'ho usato su un massimo di 250 database da tavolo / 10 GB (su un server veloce) e il tempo di risposta è a dir poco sorprendente.
Funzione PHP:
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
questo modo:$mysqli = new mysqli('localhost', 'root', 'hunter2', 'my_database');
$colum
con in "`$colum`"
modo che i campi che sono parole riservate non causino problemi
Puoi utilizzare questo progetto: http://code.google.com/p/anywhereindb
Questo cercherà tutti i dati in tutta la tabella.
Se si sta evitando stored procedures
come la peste, o sono in grado di fare una mysql_dump
causa di permessi, o l'esecuzione in altri vari motivi.
Suggerirei un approccio in tre fasi come questo:
1) Dove questa query crea un gruppo di query come set di risultati.
# =================
# 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%'
;
I risultati dovrebbero apparire così:
2) È quindi possibile solo Right Click
e utilizzare ilCopy Row (tab-separated)
3) Incolla i risultati in una nuova finestra di query ed esegui il contenuto del tuo cuore.
Dettaglio: escludo gli schemi di sistema che potresti non vedere di solito nel tuo banco di lavoro se non hai l'opzione Show Metadata and Internal Schemas
selezionata.
Ho fatto questo per fornire un modo rapido a ANALYZE
un intero HOST o DB, se necessario, o per eseguire OPTIMIZE
dichiarazioni per supportare i miglioramenti delle prestazioni.
Sono sicuro che ci sono diversi modi in cui puoi fare questo, ma ecco cosa funziona per me:
-- ========================================== 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';
Testato sulla versione MySQL: 5.6.23
ATTENZIONE: NON ESEGUIRE QUESTO SE:
- Ti preoccupi di causare i blocchi della tabella (tieni d'occhio le connessioni dei tuoi client)
Non sei sicuro di ciò che stai facendo.
Stai cercando di far arrabbiare il tuo DBA. (potresti avere persone alla tua scrivania con la rapidità .)
Saluti, Jay; -]
Ho anche fatto il mio crawler mysql per cercare una configurazione di wordpress, non sono riuscito a trovarlo nell'interfaccia e nel database e i dump del database erano troppo pesanti e illeggibili. Devo dire che non posso farne a meno ora.
Funziona come quello di @Olivier, ma gestisce nomi di database / tabelle esotici ed è LIKE-joker sicuro.
<?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++;
}
}
L'esecuzione di questo script potrebbe generare qualcosa di simile:
---------------------------------------------------
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
Questa è la query più semplice per recuperare tutte le colonne e le tabelle
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
Tutte le tabelle o quelle con una stringa specifica nel nome possono essere ricercate tramite la scheda Cerca in phpMyAdmin.
Buona query ... \ ^. ^ /
Utilizzando MySQL Workbench è facile selezionare più tabelle ed eseguire una ricerca di testo in tutte quelle tabelle del DB ;-)
Anche se questa domanda è vecchia, ecco come puoi farlo se stai usando mysql workbench 6.3. (Molto probabilmente funziona anche con altre versioni)
Fai clic con il pulsante destro del mouse sullo schema e su "Cerca dati tabella", inserisci il tuo valore e premi "Avvia ricerca". Questo è tutto.
Ecco la mia soluzione per questo
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')
, mi manca questo errore: # 1267 - Mix illegale di regole di confronto (utf8_general_ci, IMPLICIT) e (utf8_unicode_ci, IMPLICIT) per l'operazione '=' Riesci a risolverlo? Grazie!
Uso HeidiSQL è uno strumento utile e affidabile progettato per gli sviluppatori Web che utilizzano il famoso server MySQL.
In HeidiSQL puoi premere shift + ctrl + f e puoi trovare del testo sul server in tutte le tabelle. Questa opzione è molto utile.
Puoi usare
SHOW TABLES;
Quindi ottenere le colonne in quelle tabelle (in un ciclo) con
SHOW COLUMNS FROM table;
e poi con quelle informazioni crea molte domande che puoi anche UNION se necessario.
Ma questo è estremamente pesante nel database. Soprattutto se stai effettuando una ricerca COME.
SHOW TABLES FROM <db_name>
è più preciso
Questa soluzione
a) è solo MySQL, non è necessaria altra lingua
eb) restituisce risultati SQL, pronti per l'elaborazione!
#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
quando eseguo la tua query in Phpmyadmin per la ricerca nell'intero database
Ho modificato un po 'la risposta PHP di Olivier a:
mostra il numero totale di risultati
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;
}
Ho costruito su una risposta precedente e ho questo, qualche imbottitura extra solo per poter unire comodamente tutto l'output:
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
Prima esegui questo, quindi incolla ed esegui il risultato (nessuna modifica) e verranno visualizzati tutti i nomi e le colonne della tabella in cui viene utilizzato il valore.
WHERE NOT A.TABLE_SCHEMA IN ('mysql', 'innodb', 'performance_schema', 'information_schema')
o anche meglio, eseguirlo, controllare gli schemi utilizzati e impostare lo schema usato nel punto invece di escludere tutti gli altri.
l'ho fatto funzionare. devi solo cambiare le variabili
$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>";
L'ho fatto usando HeidiSQL. Non è facile da trovare, ma premendo Ctrl + Maiusc + F viene visualizzata la finestra di dialogo "Strumenti tabella". Quindi selezionare ciò che si desidera cercare (dal database completo alla singola tabella) e immettere il valore "Testo da trovare" e fare clic su "Trova". L'ho trovato sorprendentemente veloce (870 MiB db in meno di un minuto)
Ho usato Union per mettere insieme le query. Non so se è il modo più efficiente, ma funziona.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
C'è una bella biblioteca per leggere tutti i tavoli, 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
}
Non so se questo è solo nelle versioni recenti, ma facendo clic destro Tables
sull'opzione nel Navigator
riquadro si apre un'opzione chiamata Search Table Data
. Questo apre una casella di ricerca in cui si compila la stringa di ricerca e si preme la ricerca.
È necessario selezionare la tabella in cui si desidera cercare nel riquadro sinistro. Ma se tieni premuto MAIUSC e selezioni come 10 tabelle alla volta, MySql può gestirlo e restituire i risultati in pochi secondi.
Per chiunque cerchi opzioni migliori! :)