Je souhaite 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 suivante:
SELECT * FROM * WHERE * LIKE '%stuff%'
Est-il possible de faire quelque chose comme ça?
Vous pouvez jeter un coup d'œil dans le schéma information_schema
. Il contient une liste de toutes les tables et de tous les champs contenus dans une table. Vous pouvez ensuite exécuter des requêtes en utilisant les informations que vous avez obtenues à partir de cette table.
Les tables impliquées sont SCHEMATA, TABLES et COLUMNS. Il existe des clés étrangères permettant de définir exactement comment les tables sont créées dans un schéma.
Vous pouvez faire un SQLDump
de la base de données (et ses données) puis rechercher ce fichier.
Si vous avez installé phpMyAdmin, utilisez sa fonctionnalité 'Recherche'.
Je l'ai utilisé sur un maximum de 250 bases de données de table/10 Go (sur un serveur rapide) et le temps de réponse est tout simplement incroyable.
Vous pouvez utiliser ce projet: http://code.google.com/p/anywhereindb
Cela recherchera toutes les données de toutes les tables.
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()){
$colum = $r2[0];
$sql_search_fields[] = $colum." 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;
}
Si vous évitez stored procedures
comme le fléau, ou êtes incapable de faire un mysql_dump
en raison d'autorisations, ou pour toute autre raison.
Je suggérerais une approche en trois étapes comme celle-ci:
1) Où cette requête génère un ensemble de requêtes en tant que jeu 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 simplement Right Click
et utiliser la fonction Copy Row (tab separated)
3) Coller les résultats dans une nouvelle fenêtre de requête et les exécuter à votre guise.
Détail: J'exclus les schémas système que vous ne pouvez généralement pas voir dans votre plan de travail, sauf si vous avez coché l'option Show Metadata and Internal Schemas
.
Je l’ai fait pour fournir un moyen rapide de ANALYZE
un hôte entier ou une base de données si nécessaire, ou pour exécuter des instructions OPTIMIZE
afin de 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 CE SI:
- Vous êtes préoccupé par les verrous de table (gardez un œil sur vos connexions client)
Vous ne savez pas ce que vous faites.
Vous essayez de vous mettre en colère, DBA. (vous pouvez avoir des gens à votre bureau avec le quickness.)
A bientôt, Jay;]
J'ai également fait mon propre robot d'exploration mysql pour rechercher une configuration wordpress, j'étais incapable de la trouver dans l'interface et la base de données, et les sauvegardes de la base de données étaient trop lourdes et illisibles. Je dois dire que je ne peux plus m'en passer maintenant.
Cela fonctionne comme celui de @Olivier, mais il gère des noms de bases de données/tables exotiques et est sécurisé avec 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 peut générer quelque chose comme:
---------------------------------------------------
Table 'customers' contains 1 rows matching '*iemblo'.
---------------------------------------------------
Row #1: email_client: [email protected]
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: [email protected]
C'est la requête la plus simple pour récupérer toutes les colonnes et tous les tableaux.
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
Toutes les tables ou celles avec un nom de chaîne spécifique peuvent être recherchées via l'onglet Recherche de phpMyAdmin.
Avoir une bonne question ...\^. ^ /
Avec MySQL Workbench, il est facile de sélectionner plusieurs tables et d’effectuer une recherche de texte dans toutes les tables de la base de données ;-)
HeidiSQL est un outil utile et fiable, conçu pour les développeurs Web utilisant le célèbre serveur MySQL.
Dans HeidiSQL, vous pouvez appuyer sur Maj + Ctrl + F et trouver du texte sur le serveur dans tous les tableaux. Cette option est très utile.
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;
C’est le moyen le plus simple que je connaisse . Sélectionnez votre base de données dans PHPMyAdmin, allez à l’onglet "Rechercher" et écrivez ce que vous voulez trouver et où vous le souhaitez. Sélectionnez toutes les tables si vous voulez rechercher les mots de toutes les tables. Puis "GO" et regardez le résultat .
Bien que cette question soit ancienne, voici comment vous pouvez le faire si vous utilisez mysql workbench 6.3. (Très probablement, cela fonctionne aussi pour d'autres versions)
Faites un clic droit sur votre schéma et "Rechercher dans la table", entrez votre valeur et cliquez sur "Lancer la recherche". C'est tout.
Vous pourriez utiliser
SHOW TABLES;
Puis obtenez les colonnes dans ces tables (en boucle) avec
SHOW COLUMNS FROM table;
et puis avec cette information créer beaucoup de nombreuses requêtes que vous pouvez également UNION si vous avez besoin.
Mais c'est extrêmement lourd sur la base de données. Surtout si vous faites une recherche comme.
J'ai modifié un peu la réponse PHP d'Olivier à:
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;
}
Le vidage du fichier SQL était probablement le plus rapide et le plus rapide pour moi. Aussi découvert un autre problème de toute façon ..
Cette solution
a) n’est que MySQL, aucune autre langue n’est nécessaire, et
b) renvoie les résultats SQL, prêts au 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;
je dois le faire fonctionner. il vous 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>";
Je me suis basé 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
D'abord, vous exécutez ceci, puis collez 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.
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 s'il s'agit uniquement des versions récentes, mais un clic droit sur l'option Tables
dans le volet Navigator
ouvre une option appelée Search Table Data
. Cela ouvre une boîte de recherche où vous remplissez la chaîne de recherche et cliquez sur Rechercher.
Vous devez sélectionner la table dans laquelle vous souhaitez effectuer une recherche dans le volet gauche. Mais si vous maintenez la touche shift enfoncée et que vous sélectionnez environ 10 tables à la fois, MySql peut gérer cela et renvoyer les résultats en quelques secondes.
Pour tous ceux qui recherchent de meilleures options! :)
Exportez la base de données complète et recherchez dans le fichier .sql.
J'ai fait cela en utilisant HeidiSQL. Ce n'est pas facile à trouver, mais en appuyant sur Ctrl + Maj + F, la boîte de dialogue "outils de tableau" s'affiche. Sélectionnez ensuite ce que vous souhaitez rechercher (base de données complète dans une seule table), entrez la valeur "Texte à rechercher" et cliquez sur "Rechercher". Je l'ai trouvé étonnamment rapide (870 Mo en moins d'une minute)
J'ai utilisé Union pour enchaîner des 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%';