Je veux rechercher dans tous les champs de toutes les tables d'une base de données MySQL une chaîne donnée, en utilisant éventuellement la syntaxe comme:
SELECT * FROM * WHERE * LIKE '%stuff%'
Est-il possible de faire quelque chose comme ça?
Je veux rechercher dans tous les champs de toutes les tables d'une base de données MySQL une chaîne donnée, en utilisant éventuellement la syntaxe comme:
SELECT * FROM * WHERE * LIKE '%stuff%'
Est-il possible de faire quelque chose comme ça?
Réponses:
Vous pouvez jeter un œil au information_schema
schéma. Il a une liste de toutes les tables et de tous les champs qui se trouvent dans une table. Vous pouvez ensuite exécuter des requêtes en utilisant les informations que vous avez obtenues de ce tableau.
Les tableaux concernés sont SCHEMATA, TABLES et COLUMNS. Il existe des clés étrangères telles que vous pouvez créer exactement comment les tables sont créées dans un schéma.
information_schema
est une base de données, pas une table. Quelques précisions sur le tableau dans lequel effectuer la recherche information_schema
seraient utiles!
Vous pouvez faire une partie SQLDump
de la base de données (et de ses données) puis rechercher ce fichier.
mysqldump -T
qui crée deux fichiers par table dans un répertoire spécifié. J'ai ensuite grep <search> *
dans le répertoire, et ce qui est retourné est le fichier tablename.txt ou .sql. Le fichier txt contient les données de la table (délimité par des tabulations, renommer en csv pour ouvrir dans Excel), et le sql contient la définition de la table, vous l'avez deviné: SQL. De cette façon, vous recherchez tout et il est facile de préciser où se trouvent vos données. Cette méthode peut cependant être assez difficile à mettre en œuvre dans certains environnements. Le débordement de pile est très utile ici.
Si vous avez installé phpMyAdmin, utilisez sa fonction de recherche.
Je l'ai utilisé sur jusqu'à 250 bases de données de table / 10 Go (sur un serveur rapide) et le temps de réponse est tout simplement incroyable.
Fonction 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
comme ceci:$mysqli = new mysqli('localhost', 'root', 'hunter2', 'my_database');
$colum
par "`$colum`"
afin que les champs qui sont des mots réservés ne causent pas de problèmes
Vous pouvez utiliser ce projet: http://code.google.com/p/anywhereindb
Cela va rechercher toutes les données dans toutes les tables.
Si vous évitez stored procedures
comme la peste ou si vous ne pouvez pas le faire en mysql_dump
raison d'autorisations ou si vous rencontrez d' autres raisons.
Je suggérerais une approche en trois étapes comme celle-ci:
1) Où cette requête crée un tas de requêtes en tant qu'ensemble de résultats.
# =================
# 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%'
;
Les résultats devraient ressembler à ceci:
2) Vous pouvez alors juste Right Click
et utiliser laCopy Row (tab-separated)
3) Collez les résultats dans une nouvelle fenêtre de requête et exécutez le contenu de votre cœur.
Détail: j'exclus les schémas système que vous ne voyez généralement pas dans votre plan de travail, sauf si l'option est Show Metadata and Internal Schemas
cochée.
J'ai fait cela pour fournir un moyen rapide à ANALYZE
un hôte ou une base de données entière si nécessaire ou pour exécuter des OPTIMIZE
instructions pour prendre en charge les améliorations de performances.
Je suis sûr qu'il existe différentes façons de procéder, mais voici ce qui fonctionne pour moi:
-- ========================================== 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';
Testé sur la version MySQL: 5.6.23
AVERTISSEMENT: NE PAS EXÉCUTER CECI SI:
- Vous souhaitez créer des verrous de table (gardez un œil sur vos connexions client)
Vous n'êtes pas sûr de ce que vous faites.
Vous essayez de vous irriter DBA. (vous pouvez avoir des gens à votre bureau avec la rapidité .)
Santé, Jay; -]
J'ai également fait mon propre robot mysql pour rechercher une configuration wordpress, je n'ai pas pu le trouver à la fois dans l'interface et la base de données, et les vidages de base de données étaient trop lourds et illisibles. Je dois dire que je ne peux plus m'en passer maintenant.
Il fonctionne comme celui de @Olivier, mais il gère les noms de base de données / tables exotiques et est sûr comme LIKE-joker.
<?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'exécution de ce script pourrait produire quelque chose comme:
---------------------------------------------------
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
Il s'agit de la requête la plus simple pour récupérer toutes les colonnes et tables
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
Toutes les tables ou celles avec une chaîne spécifique dans le nom peuvent être recherchées via l'onglet Rechercher dans phpMyAdmin.
Avoir une bonne requête ... \ ^. ^ /
En utilisant MySQL Workbench, il est facile de sélectionner plusieurs tables et d'exécuter une recherche de texte dans toutes ces tables de la base de données ;-)
Bien que cette question soit ancienne, voici comment vous pouvez le faire si vous utilisez mysql workbench 6.3. (Très probablement, cela fonctionne également pour d'autres versions)
Faites un clic droit sur votre schéma et "Rechercher les données de la table", entrez votre valeur et cliquez sur "Démarrer la recherche". C'est tout.
Voici ma solution pour cela
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')
, cette erreur me manque: # 1267 - Mélange illégal de classements (utf8_general_ci, IMPLICIT) et (utf8_unicode_ci, IMPLICIT) pour l'opération '=' Pouvez-vous le corriger? Merci!
C'est la manière simple que je connais. Sélectionnez votre base de données dans PHPMyAdmin, allez dans l'onglet "Rechercher" et écrivez ce que vous voulez trouver et où vous allez chercher. Sélectionnez tous les tableaux si vous recherchez les mots de tous les tableaux. Ensuite, "GO" et regardez le résultat.
J'utilise HeidiSQL est un outil utile et fiable conçu pour les développeurs Web utilisant le populaire serveur MySQL.
Dans HeidiSQL, vous pouvez appuyer sur shift + ctrl + f et vous pouvez trouver du texte sur le serveur dans toutes les tables. Cette option est très utile.
Vous pourriez utiliser
SHOW TABLES;
Ensuite, récupérez les colonnes de ces tables (en boucle) avec
SHOW COLUMNS FROM table;
puis avec ces informations, créez de nombreuses requêtes que vous pouvez également UNION si vous en avez besoin.
Mais c'est extrêmement lourd sur la base de données. Surtout si vous effectuez une recherche COMME.
SHOW TABLES FROM <db_name>
est plus précis
Cette solution
a) n'est que MySQL, aucun autre langage n'est nécessaire, et
b) retourne les résultats SQL, prêts pour le traitement!
#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
lorsque j'exécute votre requête dans Phpmyadmin pour la recherche dans la base de données entière
J'ai un peu modifié la réponse PHP d'Olivier pour:
afficher le nombre total de résultats
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;
}
J'ai construit sur une réponse précédente et j'ai ceci, un rembourrage supplémentaire juste pour pouvoir joindre facilement toutes les sorties:
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
Commencez par l'exécuter, puis collez-le et exécutez le résultat (sans modification) et il affichera tous les noms de table et les colonnes où la valeur est utilisée.
WHERE NOT A.TABLE_SCHEMA IN ('mysql', 'innodb', 'performance_schema', 'information_schema')
ou même mieux, l'exécuter, vérifier les schémas utilisés et définir le schéma utilisé dans le lieu en excluant tous les autres.
je l'ai fait fonctionner. il suffit de changer les variables
$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>";
J'ai fait cela en utilisant HeidiSQL. Ce n'est pas facile à trouver, mais en appuyant sur Ctrl + Maj + F, il affiche la boîte de dialogue "Outils de table". Sélectionnez ensuite ce que vous souhaitez rechercher (base de données complète dans une seule table) et entrez la valeur "Texte à rechercher" et cliquez sur "Rechercher". Je l'ai trouvé étonnamment rapide (870 Mo de dB en moins d'une minute)
J'ai utilisé Union pour enchaîner les requêtes. Je ne sais pas si c'est le moyen le plus efficace, mais ça marche.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
Il y a une belle bibliothèque pour lire toutes les tables, 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
}
Je ne sais pas si c'est uniquement dans les versions récentes, mais un clic droit sur l' Tables
option dans le Navigator
volet affiche une option appelée Search Table Data
. Cela ouvre une boîte de recherche où vous remplissez la chaîne de recherche et appuyez sur Rechercher.
Vous devez sélectionner le tableau dans lequel vous souhaitez rechercher dans le volet gauche. Mais si vous maintenez la touche Maj enfoncée et sélectionnez 10 tables à la fois, MySql peut gérer cela et retourner des résultats en quelques secondes.
Pour tous ceux qui recherchent de meilleures options! :)