I want to search in all fields from all tables of a MySQL database a given string, possibly using syntax as:
SELECT * FROM * WHERE * LIKE '%stuff%'
Is it possible to do something like this?
You could do an SQLDump of the database (and its data) then search that file.
If you have phpMyAdmin installed use its 'Search' feature.
Select your DB
Be sure you do have a DB selected (i.e. not a table, otherwise you'll get a completely different search dialog)
Click 'Search' tab
Choose the search term you want
Choose the tables to search
I have used this on up to 250 table/10GB databases (on a fast server) and the response time is nothing short of amazing.
You can peek into the information_schema schema. It has a list of all tables and all fields that are in a table. You can then run queries using the information that you have gotten from this table.
The tables involved are SCHEMATA, TABLES and COLUMNS. There are foreign keys such that you can build up exactly how the tables are created in a schema.
PHP function:
function searchAllDB($search){
global $mysqli;
$out = Array();
$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()){
$column = $r2[0];
$sql_search_fields[] = "`".$column."` like('%".$mysqli->real_escape_string($search)."%')";
}
$rs2->close();
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs3 = $mysqli->query($sql_search);
$out[$table] = $rs3->num_rows."\n";
if($rs3->num_rows > 0){
$rs3->close();
}
}
$rs->close();
}
return $out;
}
print_r(searchAllDB("search string"));
This is the simple way that's i know.
Select your DB in PHPMyAdmin, and go to the "Search" tab and write what you want to find and where you will searching for. Select all tables if you will search the words from all tables. Then "GO" and look the result.
If you are avoiding stored procedures like the plague, or are unable to do a mysql_dump due to permissions, or running into other various reasons.
I would suggest a three-step approach like this:
1) Where this query builds a bunch of queries as a result set.
# =================
# 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%'
;
Results should look like this:
2) You can then just Right Click and use the Copy Row (tab-separated)
3) Paste results in a new query window and run to your heart's content.
Detail: I exclude system schema's that you may not usually see in your workbench unless you have the option Show Metadata and Internal Schemas checked.
I did this to provide a quick way to ANALYZE an entire HOST or DB if needed or to run OPTIMIZE statements to support performance improvements.
I'm sure there are different ways you may go about doing this but here’s what works for 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';
Tested On MySQL Version: 5.6.23
WARNING: DO NOT RUN THIS IF:
You are concerned with causing Table-locks (keep an eye on your client-connections)
You are unsure about what you are doing.
You are trying to anger you DBA. (you may have people at your desk with the quickness.)
Cheers, Jay ;-]
It's been twelve years and no one posted an answer to the following question:
I want to search in all fields from all tables of a MySQL database for a given string
Anwsers include GUIs, vague ideas, syntax errors, procedures needing table names or prefixes and all sorts of contortions. Here's an actual, working, tested, simple to use answer building on multiple previous answers but also adding the primary key to the results.
DROP PROCEDURE IF EXISTS findAll;
DELIMITER $$
CREATE PROCEDURE findAll( IN `search` TEXT )
BEGIN
SET SESSION group_concat_max_len := ##max_allowed_packet;
SELECT GROUP_CONCAT(
"SELECT '", c1.TABLE_NAME, "' AS `table`, '", c1.COLUMN_NAME, "' AS `column`, ",
"CONCAT_WS(',', ", (SELECT GROUP_CONCAT(c2.column_name) FROM `information_schema`.`columns` c2 WHERE c1.TABLE_SCHEMA=c2.TABLE_SCHEMA AND c1.TABLE_NAME=c2.TABLE_NAME AND c2.COLUMN_KEY='PRI') ,") AS pri,",
c1.COLUMN_NAME, " AS value FROM ", c1.TABLE_NAME,
" WHERE `",c1.COLUMN_NAME,"` LIKE '%", search, "%'" SEPARATOR "\nUNION\n") AS col
INTO #sql
FROM information_schema.columns c1
WHERE c1.TABLE_SCHEMA = DATABASE();
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
That's it. You can now do CALL findAll('foobar');
Except not. You will run into two problems:
MySQL error 1436: Thread stack overrun
Prepared statement needs to be re-prepared.
Add the following two lines to /etc/mysql/mysql.conf.d/mysqld.cnf or wherever your cnf is or save them in a separate file and copy into the conf.d directory.
thread_stack = 2M
table_definition_cache = 5000
And yes, obviously this shouldn't be run on production because it's insecure and it'll tank your performance.
I also did my own mysql crawler to search some wordpress configuration, was unable to find it in both the interface and database, and database dumps were too heavy and unreadable. I must say I can't do without it now.
It works like the one from #Olivier, but it manages exotic database / table names and is LIKE-joker safe.
<?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++;
}
}
Running this script could output something like:
---------------------------------------------------
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
Using MySQL Workbench it's easy to select several tables and run a search for text in all those tables of the DB ;-)
This is the simplest query to retrive all Columns and Tables
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
All the tables or those with specific string in name could be searched via Search tab in phpMyAdmin.
Have Nice Query... \^.^/
I am use HeidiSQL is a useful and reliable tool designed for web developers using the popular MySQL server.
In HeidiSQL you can push shift + ctrl + f and you can find text on the server in all tables. This option is very usefully.
Although this question is old , here is how you can do it if you are using mysql workbench 6.3. ( Most likely it also works for other versions)
Right click your schema and "Search table data" , enter your value and hit "Start Search". Thats it.
Here is my solution for this
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;
MySQL Workbench
Here are some instructions.
Download and install MSQL Workbench.
https://www.mysql.com/products/workbench/
When installing, it might require you to install Visual Studio C++ Redistributable. You can get it here:
https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
x64: vc_redist.x64.exe (for 64 bit Windows)
When you open MySQL Workbench, you will have to enter your host name, user and password.
There is a Schemas tab on the side menu bar, click on the Schemas tab, then double click on a database to select the database you want to search.
Then go to menu Database - Search Data, and enter the text you are searching for, click on Start Search.
HeidiSql
Download and install HeidiSql
https://www.heidisql.com/download.php
Enter your hostname, user and password.
Hit Ctrl+Shift+F to search text.
This solution
a) is only MySQL, no other language needed, and
b) returns SQL results, ready for processing!
#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;
You could use
SHOW TABLES;
Then get the columns in those tables (in a loop) with
SHOW COLUMNS FROM table;
and then with that info create many many queries which you can also UNION if you need.
But this is extremely heavy on the database. Specially if you are doing a LIKE search.
To search a string in all tables in a database run the following command on CLI.
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString"
Or,
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString" > searchingString.sql
I modified the PHP answer of Olivier a bit to:
print out the results in which the string was found
omit tables without results
also show output if column names match the search input
show total number of results
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;
}
I built on a previous answer and have this, some extra padding just to be able to conveniently join all the 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
First you run this, then paste in and run the result (no editing) and it will display all the table names and columns where the value is used.
Even if the following proposal should not be considered as a final solution you can achieve the goal by doing something like this:
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;
Please remember that:
Options: group_concat_max_len and limit 1000000 not always are needed, it will depends of your server/IDE configuration. Just in case I added them.
After executing this you will get a 3 column response: [table_name], [column_name], [matches]
Column 'matches' is the number of occurrences in the given table/column.
This query is very fast.
DISCLAIMER: It would be useful only for personal use, in other words please don't use it in a production system, because it is sensitive to SQL Injection attacks given that the search parameter is concatenated with other strings.
If you want to create a prod. ready function, then you will need to create a store procedure with a LOOP.
i got this to work. you just need to change the 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>";
I have done this using HeidiSQL.
It's not easy to find but by pressing Ctrl+Shift+F it displays the "table tools" dialogue. Then select what you want to search (Full database to single table) and enter the "Text to find" value and click "Find". I found it surprisingly fast (870MiB db in less than a minute)
In case 23 answers is not enough, here are 2 more... Depending on database structure and content, you may find one them to actually be a quick and simple solution.
For fans of shell one-liners, here is a long one (actually on 2 lines to use variables):
cmd='mysql -u Username -pYour_Password -D Your_Database' # <-- Adapt this
$cmd -s -e 'SHOW TABLES' | while read table; do echo "=== $table ==="; $cmd -B -s -e "SELECT * FROM $table" | grep 'Your_Search'; done
Or on multiple lines to make it more readable:
$cmd -s -e 'SHOW TABLES' \
| while read table; do
echo "=== $table ===";
$cmd -B -s -e "SELECT * FROM $table" \
| grep 'Your_Search';
done
-s (--silent) is to suppress the column name headers
-B (--batch) escapes special characters like newlines, so we get the whole record when using grep
And for Perl fans, this will let you use regular expressions:
# perl -MDBI -le '($db,$u,$p)=#ARGV; $dbh=DBI->connect("dbi:mysql:dbname=$db",$u,$p); foreach $table ($dbh->tables()) {print "$table\n"; foreach $r ($dbh->selectall_array("SELECT * FROM $table")) {$_=join("\t", #$r); print $_ if (/Your_Regex/);}}' Your_Database Username Your_Password
Which in a "real" Perl script could be something like this:
#!/usr/bin/perl
use strict;
use open qw(:std :utf8);
use DBI;
my $db_host = 'localhost';
my $db = 'Your_Database';
my $db_user = 'Username';
my $db_pass = 'Your_Password';
my $search = qr/Your_regex_Search/;
# https://metacpan.org/pod/DBD::mysql
my $dbh = DBI->connect( "dbi:mysql:dbname=$db;host=$db_host", $db_user, $db_pass,
{ mysql_enable_utf8mb4 => 1 }
) or die "Can't connect: $DBI::errstr\n";
foreach my $table ( $dbh->tables() ) {
my $sth = $dbh->prepare("SELECT * FROM $table")
or die "Can't prepare: ", $dbh->errstr;
$sth->execute
or die "Can't execute: ", $sth->errstr;
my #results;
while (my #row = $sth->fetchrow()) {
local $_ = join("\t", #row);
if ( /$search/ ) {
push #results, $_;
}
}
$sth->finish;
next unless #results;
print "*** TABLE $table :\n",
join("\n---------------\n", #results),
"\n" . "=" x 20 . "\n";
}
$dbh->disconnect;
I used Union to string together queries. Don't know if it's the most efficient way, but it works.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
There is a nice library for reading all 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
}
I don't know if this is only in the recent versions, but right clicking on the Tables option in the Navigator pane pops up an option called Search Table Data. This opens up a search box where you fill in the search string and hit search.
You do need to select the table you want to search in on the left pane. But if you hold down shift and select like 10 tables at a time, MySql can handle that and return results in seconds.
For anyone that is looking for better options! :)
If you are not using it on code level, you just want to check the information, you could export the entire database as SQL and then search on the text editor.
Related
I want to search in all fields from all tables of a MySQL database a given string, possibly using syntax as:
SELECT * FROM * WHERE * LIKE '%stuff%'
Is it possible to do something like this?
You could do an SQLDump of the database (and its data) then search that file.
If you have phpMyAdmin installed use its 'Search' feature.
Select your DB
Be sure you do have a DB selected (i.e. not a table, otherwise you'll get a completely different search dialog)
Click 'Search' tab
Choose the search term you want
Choose the tables to search
I have used this on up to 250 table/10GB databases (on a fast server) and the response time is nothing short of amazing.
You can peek into the information_schema schema. It has a list of all tables and all fields that are in a table. You can then run queries using the information that you have gotten from this table.
The tables involved are SCHEMATA, TABLES and COLUMNS. There are foreign keys such that you can build up exactly how the tables are created in a schema.
PHP function:
function searchAllDB($search){
global $mysqli;
$out = Array();
$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()){
$column = $r2[0];
$sql_search_fields[] = "`".$column."` like('%".$mysqli->real_escape_string($search)."%')";
}
$rs2->close();
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs3 = $mysqli->query($sql_search);
$out[$table] = $rs3->num_rows."\n";
if($rs3->num_rows > 0){
$rs3->close();
}
}
$rs->close();
}
return $out;
}
print_r(searchAllDB("search string"));
This is the simple way that's i know.
Select your DB in PHPMyAdmin, and go to the "Search" tab and write what you want to find and where you will searching for. Select all tables if you will search the words from all tables. Then "GO" and look the result.
If you are avoiding stored procedures like the plague, or are unable to do a mysql_dump due to permissions, or running into other various reasons.
I would suggest a three-step approach like this:
1) Where this query builds a bunch of queries as a result set.
# =================
# 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%'
;
Results should look like this:
2) You can then just Right Click and use the Copy Row (tab-separated)
3) Paste results in a new query window and run to your heart's content.
Detail: I exclude system schema's that you may not usually see in your workbench unless you have the option Show Metadata and Internal Schemas checked.
I did this to provide a quick way to ANALYZE an entire HOST or DB if needed or to run OPTIMIZE statements to support performance improvements.
I'm sure there are different ways you may go about doing this but here’s what works for 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';
Tested On MySQL Version: 5.6.23
WARNING: DO NOT RUN THIS IF:
You are concerned with causing Table-locks (keep an eye on your client-connections)
You are unsure about what you are doing.
You are trying to anger you DBA. (you may have people at your desk with the quickness.)
Cheers, Jay ;-]
It's been twelve years and no one posted an answer to the following question:
I want to search in all fields from all tables of a MySQL database for a given string
Anwsers include GUIs, vague ideas, syntax errors, procedures needing table names or prefixes and all sorts of contortions. Here's an actual, working, tested, simple to use answer building on multiple previous answers but also adding the primary key to the results.
DROP PROCEDURE IF EXISTS findAll;
DELIMITER $$
CREATE PROCEDURE findAll( IN `search` TEXT )
BEGIN
SET SESSION group_concat_max_len := ##max_allowed_packet;
SELECT GROUP_CONCAT(
"SELECT '", c1.TABLE_NAME, "' AS `table`, '", c1.COLUMN_NAME, "' AS `column`, ",
"CONCAT_WS(',', ", (SELECT GROUP_CONCAT(c2.column_name) FROM `information_schema`.`columns` c2 WHERE c1.TABLE_SCHEMA=c2.TABLE_SCHEMA AND c1.TABLE_NAME=c2.TABLE_NAME AND c2.COLUMN_KEY='PRI') ,") AS pri,",
c1.COLUMN_NAME, " AS value FROM ", c1.TABLE_NAME,
" WHERE `",c1.COLUMN_NAME,"` LIKE '%", search, "%'" SEPARATOR "\nUNION\n") AS col
INTO #sql
FROM information_schema.columns c1
WHERE c1.TABLE_SCHEMA = DATABASE();
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
That's it. You can now do CALL findAll('foobar');
Except not. You will run into two problems:
MySQL error 1436: Thread stack overrun
Prepared statement needs to be re-prepared.
Add the following two lines to /etc/mysql/mysql.conf.d/mysqld.cnf or wherever your cnf is or save them in a separate file and copy into the conf.d directory.
thread_stack = 2M
table_definition_cache = 5000
And yes, obviously this shouldn't be run on production because it's insecure and it'll tank your performance.
I also did my own mysql crawler to search some wordpress configuration, was unable to find it in both the interface and database, and database dumps were too heavy and unreadable. I must say I can't do without it now.
It works like the one from #Olivier, but it manages exotic database / table names and is LIKE-joker safe.
<?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++;
}
}
Running this script could output something like:
---------------------------------------------------
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
Using MySQL Workbench it's easy to select several tables and run a search for text in all those tables of the DB ;-)
This is the simplest query to retrive all Columns and Tables
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
All the tables or those with specific string in name could be searched via Search tab in phpMyAdmin.
Have Nice Query... \^.^/
I am use HeidiSQL is a useful and reliable tool designed for web developers using the popular MySQL server.
In HeidiSQL you can push shift + ctrl + f and you can find text on the server in all tables. This option is very usefully.
Although this question is old , here is how you can do it if you are using mysql workbench 6.3. ( Most likely it also works for other versions)
Right click your schema and "Search table data" , enter your value and hit "Start Search". Thats it.
Here is my solution for this
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;
MySQL Workbench
Here are some instructions.
Download and install MSQL Workbench.
https://www.mysql.com/products/workbench/
When installing, it might require you to install Visual Studio C++ Redistributable. You can get it here:
https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
x64: vc_redist.x64.exe (for 64 bit Windows)
When you open MySQL Workbench, you will have to enter your host name, user and password.
There is a Schemas tab on the side menu bar, click on the Schemas tab, then double click on a database to select the database you want to search.
Then go to menu Database - Search Data, and enter the text you are searching for, click on Start Search.
HeidiSql
Download and install HeidiSql
https://www.heidisql.com/download.php
Enter your hostname, user and password.
Hit Ctrl+Shift+F to search text.
This solution
a) is only MySQL, no other language needed, and
b) returns SQL results, ready for processing!
#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;
You could use
SHOW TABLES;
Then get the columns in those tables (in a loop) with
SHOW COLUMNS FROM table;
and then with that info create many many queries which you can also UNION if you need.
But this is extremely heavy on the database. Specially if you are doing a LIKE search.
To search a string in all tables in a database run the following command on CLI.
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString"
Or,
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString" > searchingString.sql
I modified the PHP answer of Olivier a bit to:
print out the results in which the string was found
omit tables without results
also show output if column names match the search input
show total number of results
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;
}
I built on a previous answer and have this, some extra padding just to be able to conveniently join all the 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
First you run this, then paste in and run the result (no editing) and it will display all the table names and columns where the value is used.
Even if the following proposal should not be considered as a final solution you can achieve the goal by doing something like this:
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;
Please remember that:
Options: group_concat_max_len and limit 1000000 not always are needed, it will depends of your server/IDE configuration. Just in case I added them.
After executing this you will get a 3 column response: [table_name], [column_name], [matches]
Column 'matches' is the number of occurrences in the given table/column.
This query is very fast.
DISCLAIMER: It would be useful only for personal use, in other words please don't use it in a production system, because it is sensitive to SQL Injection attacks given that the search parameter is concatenated with other strings.
If you want to create a prod. ready function, then you will need to create a store procedure with a LOOP.
i got this to work. you just need to change the 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>";
I have done this using HeidiSQL.
It's not easy to find but by pressing Ctrl+Shift+F it displays the "table tools" dialogue. Then select what you want to search (Full database to single table) and enter the "Text to find" value and click "Find". I found it surprisingly fast (870MiB db in less than a minute)
In case 23 answers is not enough, here are 2 more... Depending on database structure and content, you may find one them to actually be a quick and simple solution.
For fans of shell one-liners, here is a long one (actually on 2 lines to use variables):
cmd='mysql -u Username -pYour_Password -D Your_Database' # <-- Adapt this
$cmd -s -e 'SHOW TABLES' | while read table; do echo "=== $table ==="; $cmd -B -s -e "SELECT * FROM $table" | grep 'Your_Search'; done
Or on multiple lines to make it more readable:
$cmd -s -e 'SHOW TABLES' \
| while read table; do
echo "=== $table ===";
$cmd -B -s -e "SELECT * FROM $table" \
| grep 'Your_Search';
done
-s (--silent) is to suppress the column name headers
-B (--batch) escapes special characters like newlines, so we get the whole record when using grep
And for Perl fans, this will let you use regular expressions:
# perl -MDBI -le '($db,$u,$p)=#ARGV; $dbh=DBI->connect("dbi:mysql:dbname=$db",$u,$p); foreach $table ($dbh->tables()) {print "$table\n"; foreach $r ($dbh->selectall_array("SELECT * FROM $table")) {$_=join("\t", #$r); print $_ if (/Your_Regex/);}}' Your_Database Username Your_Password
Which in a "real" Perl script could be something like this:
#!/usr/bin/perl
use strict;
use open qw(:std :utf8);
use DBI;
my $db_host = 'localhost';
my $db = 'Your_Database';
my $db_user = 'Username';
my $db_pass = 'Your_Password';
my $search = qr/Your_regex_Search/;
# https://metacpan.org/pod/DBD::mysql
my $dbh = DBI->connect( "dbi:mysql:dbname=$db;host=$db_host", $db_user, $db_pass,
{ mysql_enable_utf8mb4 => 1 }
) or die "Can't connect: $DBI::errstr\n";
foreach my $table ( $dbh->tables() ) {
my $sth = $dbh->prepare("SELECT * FROM $table")
or die "Can't prepare: ", $dbh->errstr;
$sth->execute
or die "Can't execute: ", $sth->errstr;
my #results;
while (my #row = $sth->fetchrow()) {
local $_ = join("\t", #row);
if ( /$search/ ) {
push #results, $_;
}
}
$sth->finish;
next unless #results;
print "*** TABLE $table :\n",
join("\n---------------\n", #results),
"\n" . "=" x 20 . "\n";
}
$dbh->disconnect;
I used Union to string together queries. Don't know if it's the most efficient way, but it works.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
There is a nice library for reading all 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
}
I don't know if this is only in the recent versions, but right clicking on the Tables option in the Navigator pane pops up an option called Search Table Data. This opens up a search box where you fill in the search string and hit search.
You do need to select the table you want to search in on the left pane. But if you hold down shift and select like 10 tables at a time, MySql can handle that and return results in seconds.
For anyone that is looking for better options! :)
If you are not using it on code level, you just want to check the information, you could export the entire database as SQL and then search on the text editor.
I want to search in all fields from all tables of a MySQL database a given string, possibly using syntax as:
SELECT * FROM * WHERE * LIKE '%stuff%'
Is it possible to do something like this?
You could do an SQLDump of the database (and its data) then search that file.
If you have phpMyAdmin installed use its 'Search' feature.
Select your DB
Be sure you do have a DB selected (i.e. not a table, otherwise you'll get a completely different search dialog)
Click 'Search' tab
Choose the search term you want
Choose the tables to search
I have used this on up to 250 table/10GB databases (on a fast server) and the response time is nothing short of amazing.
You can peek into the information_schema schema. It has a list of all tables and all fields that are in a table. You can then run queries using the information that you have gotten from this table.
The tables involved are SCHEMATA, TABLES and COLUMNS. There are foreign keys such that you can build up exactly how the tables are created in a schema.
PHP function:
function searchAllDB($search){
global $mysqli;
$out = Array();
$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()){
$column = $r2[0];
$sql_search_fields[] = "`".$column."` like('%".$mysqli->real_escape_string($search)."%')";
}
$rs2->close();
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs3 = $mysqli->query($sql_search);
$out[$table] = $rs3->num_rows."\n";
if($rs3->num_rows > 0){
$rs3->close();
}
}
$rs->close();
}
return $out;
}
print_r(searchAllDB("search string"));
This is the simple way that's i know.
Select your DB in PHPMyAdmin, and go to the "Search" tab and write what you want to find and where you will searching for. Select all tables if you will search the words from all tables. Then "GO" and look the result.
If you are avoiding stored procedures like the plague, or are unable to do a mysql_dump due to permissions, or running into other various reasons.
I would suggest a three-step approach like this:
1) Where this query builds a bunch of queries as a result set.
# =================
# 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%'
;
Results should look like this:
2) You can then just Right Click and use the Copy Row (tab-separated)
3) Paste results in a new query window and run to your heart's content.
Detail: I exclude system schema's that you may not usually see in your workbench unless you have the option Show Metadata and Internal Schemas checked.
I did this to provide a quick way to ANALYZE an entire HOST or DB if needed or to run OPTIMIZE statements to support performance improvements.
I'm sure there are different ways you may go about doing this but here’s what works for 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';
Tested On MySQL Version: 5.6.23
WARNING: DO NOT RUN THIS IF:
You are concerned with causing Table-locks (keep an eye on your client-connections)
You are unsure about what you are doing.
You are trying to anger you DBA. (you may have people at your desk with the quickness.)
Cheers, Jay ;-]
It's been twelve years and no one posted an answer to the following question:
I want to search in all fields from all tables of a MySQL database for a given string
Anwsers include GUIs, vague ideas, syntax errors, procedures needing table names or prefixes and all sorts of contortions. Here's an actual, working, tested, simple to use answer building on multiple previous answers but also adding the primary key to the results.
DROP PROCEDURE IF EXISTS findAll;
DELIMITER $$
CREATE PROCEDURE findAll( IN `search` TEXT )
BEGIN
SET SESSION group_concat_max_len := ##max_allowed_packet;
SELECT GROUP_CONCAT(
"SELECT '", c1.TABLE_NAME, "' AS `table`, '", c1.COLUMN_NAME, "' AS `column`, ",
"CONCAT_WS(',', ", (SELECT GROUP_CONCAT(c2.column_name) FROM `information_schema`.`columns` c2 WHERE c1.TABLE_SCHEMA=c2.TABLE_SCHEMA AND c1.TABLE_NAME=c2.TABLE_NAME AND c2.COLUMN_KEY='PRI') ,") AS pri,",
c1.COLUMN_NAME, " AS value FROM ", c1.TABLE_NAME,
" WHERE `",c1.COLUMN_NAME,"` LIKE '%", search, "%'" SEPARATOR "\nUNION\n") AS col
INTO #sql
FROM information_schema.columns c1
WHERE c1.TABLE_SCHEMA = DATABASE();
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
That's it. You can now do CALL findAll('foobar');
Except not. You will run into two problems:
MySQL error 1436: Thread stack overrun
Prepared statement needs to be re-prepared.
Add the following two lines to /etc/mysql/mysql.conf.d/mysqld.cnf or wherever your cnf is or save them in a separate file and copy into the conf.d directory.
thread_stack = 2M
table_definition_cache = 5000
And yes, obviously this shouldn't be run on production because it's insecure and it'll tank your performance.
I also did my own mysql crawler to search some wordpress configuration, was unable to find it in both the interface and database, and database dumps were too heavy and unreadable. I must say I can't do without it now.
It works like the one from #Olivier, but it manages exotic database / table names and is LIKE-joker safe.
<?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++;
}
}
Running this script could output something like:
---------------------------------------------------
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
Using MySQL Workbench it's easy to select several tables and run a search for text in all those tables of the DB ;-)
This is the simplest query to retrive all Columns and Tables
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
All the tables or those with specific string in name could be searched via Search tab in phpMyAdmin.
Have Nice Query... \^.^/
I am use HeidiSQL is a useful and reliable tool designed for web developers using the popular MySQL server.
In HeidiSQL you can push shift + ctrl + f and you can find text on the server in all tables. This option is very usefully.
Although this question is old , here is how you can do it if you are using mysql workbench 6.3. ( Most likely it also works for other versions)
Right click your schema and "Search table data" , enter your value and hit "Start Search". Thats it.
Here is my solution for this
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;
MySQL Workbench
Here are some instructions.
Download and install MSQL Workbench.
https://www.mysql.com/products/workbench/
When installing, it might require you to install Visual Studio C++ Redistributable. You can get it here:
https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
x64: vc_redist.x64.exe (for 64 bit Windows)
When you open MySQL Workbench, you will have to enter your host name, user and password.
There is a Schemas tab on the side menu bar, click on the Schemas tab, then double click on a database to select the database you want to search.
Then go to menu Database - Search Data, and enter the text you are searching for, click on Start Search.
HeidiSql
Download and install HeidiSql
https://www.heidisql.com/download.php
Enter your hostname, user and password.
Hit Ctrl+Shift+F to search text.
This solution
a) is only MySQL, no other language needed, and
b) returns SQL results, ready for processing!
#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;
You could use
SHOW TABLES;
Then get the columns in those tables (in a loop) with
SHOW COLUMNS FROM table;
and then with that info create many many queries which you can also UNION if you need.
But this is extremely heavy on the database. Specially if you are doing a LIKE search.
To search a string in all tables in a database run the following command on CLI.
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString"
Or,
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString" > searchingString.sql
I modified the PHP answer of Olivier a bit to:
print out the results in which the string was found
omit tables without results
also show output if column names match the search input
show total number of results
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;
}
I built on a previous answer and have this, some extra padding just to be able to conveniently join all the 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
First you run this, then paste in and run the result (no editing) and it will display all the table names and columns where the value is used.
Even if the following proposal should not be considered as a final solution you can achieve the goal by doing something like this:
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;
Please remember that:
Options: group_concat_max_len and limit 1000000 not always are needed, it will depends of your server/IDE configuration. Just in case I added them.
After executing this you will get a 3 column response: [table_name], [column_name], [matches]
Column 'matches' is the number of occurrences in the given table/column.
This query is very fast.
DISCLAIMER: It would be useful only for personal use, in other words please don't use it in a production system, because it is sensitive to SQL Injection attacks given that the search parameter is concatenated with other strings.
If you want to create a prod. ready function, then you will need to create a store procedure with a LOOP.
i got this to work. you just need to change the 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>";
I have done this using HeidiSQL.
It's not easy to find but by pressing Ctrl+Shift+F it displays the "table tools" dialogue. Then select what you want to search (Full database to single table) and enter the "Text to find" value and click "Find". I found it surprisingly fast (870MiB db in less than a minute)
In case 23 answers is not enough, here are 2 more... Depending on database structure and content, you may find one them to actually be a quick and simple solution.
For fans of shell one-liners, here is a long one (actually on 2 lines to use variables):
cmd='mysql -u Username -pYour_Password -D Your_Database' # <-- Adapt this
$cmd -s -e 'SHOW TABLES' | while read table; do echo "=== $table ==="; $cmd -B -s -e "SELECT * FROM $table" | grep 'Your_Search'; done
Or on multiple lines to make it more readable:
$cmd -s -e 'SHOW TABLES' \
| while read table; do
echo "=== $table ===";
$cmd -B -s -e "SELECT * FROM $table" \
| grep 'Your_Search';
done
-s (--silent) is to suppress the column name headers
-B (--batch) escapes special characters like newlines, so we get the whole record when using grep
And for Perl fans, this will let you use regular expressions:
# perl -MDBI -le '($db,$u,$p)=#ARGV; $dbh=DBI->connect("dbi:mysql:dbname=$db",$u,$p); foreach $table ($dbh->tables()) {print "$table\n"; foreach $r ($dbh->selectall_array("SELECT * FROM $table")) {$_=join("\t", #$r); print $_ if (/Your_Regex/);}}' Your_Database Username Your_Password
Which in a "real" Perl script could be something like this:
#!/usr/bin/perl
use strict;
use open qw(:std :utf8);
use DBI;
my $db_host = 'localhost';
my $db = 'Your_Database';
my $db_user = 'Username';
my $db_pass = 'Your_Password';
my $search = qr/Your_regex_Search/;
# https://metacpan.org/pod/DBD::mysql
my $dbh = DBI->connect( "dbi:mysql:dbname=$db;host=$db_host", $db_user, $db_pass,
{ mysql_enable_utf8mb4 => 1 }
) or die "Can't connect: $DBI::errstr\n";
foreach my $table ( $dbh->tables() ) {
my $sth = $dbh->prepare("SELECT * FROM $table")
or die "Can't prepare: ", $dbh->errstr;
$sth->execute
or die "Can't execute: ", $sth->errstr;
my #results;
while (my #row = $sth->fetchrow()) {
local $_ = join("\t", #row);
if ( /$search/ ) {
push #results, $_;
}
}
$sth->finish;
next unless #results;
print "*** TABLE $table :\n",
join("\n---------------\n", #results),
"\n" . "=" x 20 . "\n";
}
$dbh->disconnect;
I used Union to string together queries. Don't know if it's the most efficient way, but it works.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
There is a nice library for reading all 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
}
I don't know if this is only in the recent versions, but right clicking on the Tables option in the Navigator pane pops up an option called Search Table Data. This opens up a search box where you fill in the search string and hit search.
You do need to select the table you want to search in on the left pane. But if you hold down shift and select like 10 tables at a time, MySql can handle that and return results in seconds.
For anyone that is looking for better options! :)
If you are not using it on code level, you just want to check the information, you could export the entire database as SQL and then search on the text editor.
What is the best way to check if a table exists in MySQL (preferably via PDO in PHP) without throwing an exception. I do not feel like parsing the results of "SHOW TABLES LIKE" et cetera. There must be some sort of boolean query?
Querying the information_schema database using prepared statement looks like the most reliable and secure solution.
$sql = "SELECT 1 FROM information_schema.tables
WHERE table_schema = database() AND table_name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$tableName]);
$exists = (bool)$stmt->fetchColumn();
If you're using MySQL 5.0 and later, you could try:
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '[database name]'
AND table_name = '[table name]';
Any results indicate the table exists.
From: http://www.electrictoolbox.com/check-if-mysql-table-exists/
Using mysqli I've created following function. Assuming you have an mysqli instance called $con.
function table_exist($con, $table){
$table = $con->real_escape_string($table);
$sql = "show tables like '".$table."'";
$res = $con->query($sql);
return ($res->num_rows > 0);
}
Hope it helps.
Warning: as sugested by #jcaron this function could be vulnerable to sqlinjection attacs, so make sure your $table var is clean or even better use parameterised queries.
This is posted simply if anyone comes looking for this question. Even though its been answered a bit. Some of the replies make it more complex than it needed to be.
For mysql* I used :
if (mysqli_num_rows(
mysqli_query(
$con,"SHOW TABLES LIKE '" . $table . "'")
) > 0
or die ("No table set")
){
In PDO I used:
if ($con->query(
"SHOW TABLES LIKE '" . $table . "'"
)->rowCount() > 0
or die("No table set")
){
With this I just push the else condition into or. And for my needs I only simply need die. Though you can set or to other things. Some might prefer the if/ else if/else. Which is then to remove or and then supply if/else if/else.
Here is the my solution that I prefer when using stored procedures. Custom mysql function for check the table exists in current database.
delimiter $$
CREATE FUNCTION TABLE_EXISTS(_table_name VARCHAR(45))
RETURNS BOOLEAN
DETERMINISTIC READS SQL DATA
BEGIN
DECLARE _exists TINYINT(1) DEFAULT 0;
SELECT COUNT(*) INTO _exists
FROM information_schema.tables
WHERE table_schema = DATABASE()
AND table_name = _table_name;
RETURN _exists;
END$$
SELECT TABLE_EXISTS('you_table_name') as _exists
As a "Show tables" might be slow on larger databases, I recommend using "DESCRIBE " and check if you get true/false as a result
$tableExists = mysqli_query("DESCRIBE `myTable`");
$q = "SHOW TABLES";
$res = mysql_query($q, $con);
if ($res)
while ( $row = mysql_fetch_array($res, MYSQL_ASSOC) )
{
foreach( $row as $key => $value )
{
if ( $value = BTABLE ) // BTABLE IS A DEFINED NAME OF TABLE
echo "exist";
else
echo "not exist";
}
}
Zend framework
public function verifyTablesExists($tablesName)
{
$db = $this->getDefaultAdapter();
$config_db = $db->getConfig();
$sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{$config_db['dbname']}' AND table_name = '{$tablesName}'";
$result = $db->fetchRow($sql);
return $result;
}
If the reason for wanting to do this is is conditional table creation, then 'CREATE TABLE IF NOT EXISTS' seems ideal for the job. Until I discovered this, I used the 'DESCRIBE' method above. More info here: MySQL "CREATE TABLE IF NOT EXISTS" -> Error 1050
Why you make it so hard to understand?
function table_exist($table){
$pTableExist = mysql_query("show tables like '".$table."'");
if ($rTableExist = mysql_fetch_array($pTableExist)) {
return "Yes";
}else{
return "No";
}
}
As dumb as it sounds, is there a way to do something like this:
select row_id from mytable where * like '%searched_text%';
By * here I mean "all the fields" in the table, instead of me specifying them one by one...
It is not possible with one query.
However when you do:
DESCRIBE table_name;
you get the field names which you can generate the query from.
Search in all fields from every table of a MySQL database May be useful.
Here's a solution combined with some PHP to search all fields in a specific table.
include("db_con.php");
//search all fields
$searchphrase = "banan";
$table = "apa303";
$sql_search = "select * from ".$table." where ";
$sql_search_fields = Array();
$sql = "SHOW COLUMNS FROM ".$table;
$rs = mysql_query($sql);
while($r = mysql_fetch_array($rs)){
$colum = $r[0];
$sql_search_fields[] = $colum." like('%".$searchphrase."%')";
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs2 = mysql_query($sql_search);
$out = mysql_num_rows($rs2)."\n";
echo "Number of search hits in $table " . $out;
Yes, it's called Full Text Search.
You can use MySQL's built-in Full Text Search, or use a separate product to do you text indexing such as Apache's Lucene (my personal favorite).
I was looking something like this to search in all the fields of a table. Though my table having less data so I opted 'Kilian Lindberg' answer and make the PDO function using his idea. In this function we can sent the 'search string' and 'Table name' in parameter and it will return the SQL string which we can use further as per our requirement. Thought in big tables it may slowdown the process.
function columnsTable($Search, $Table){
include("PDO_conn_detail.php"); /* your PDO mysql connection file */
$srchSQLstr = "SELECT * FROM $Table WHERE ";
$tableFields = Array();
$colSQL = $conn->prepare("SHOW COLUMNS FROM $Table");
$colSQL->execute();
while ($result_colSQL = $colSQL->fetch(PDO::FETCH_ASSOC)){
$tableFields[] = $result_colSQL[Field]." LIKE ('%".$Search."%')";
}
$srchSQLstr .= implode(" OR ", $tableFields);
return $srchSQLstr;
}
Use like this
select row_id from mytable where '%searched_text%' IN ('column1','column2','column3','column4','column5');
This solution make it possible by Ms Sql Server via Linked server
DECLARE #searchTxt VARCHAR(100) = 'searching text'
DECLARE curr CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
select * from openquery (BITRIX, 'SELECT table_name, column_name FROM information_schema.columns where table_schema = ''bitrix_50'' and data_type = ''varchar'' and table_name not like ''b_mail%''')
DECLARE #tName VARCHAR(100), #cName VARCHAR(100), #sql NVARCHAR(4000), #cnt INT
OPEN curr
FETCH NEXT FROM curr INTO #tName, #cName
WHILE (##FETCH_STATUS=0)
BEGIN
SET #sql = 'select #cnt=cnt from openquery (BITRIX, ''SELECT count(*) cnt FROM ' + #tName + ' WHERE ' + #cName + ' LIKE ''''%' + #searchTxt + '%'''''')'
BEGIN TRY
EXECUTE sp_executesql #sql, N'#cnt int OUTPUT', #cnt=#cnt OUTPUT
IF (#cnt>0)
PRINT #sql
END TRY
BEGIN CATCH
PRINT N'Error on: ' + #sql
END CATCH
FETCH NEXT FROM curr INTO #tName, #cName
END
CLOSE curr
DEALLOCATE curr
Access MySQL data from SQL Server via a Linked Server
He is a complete solution,,is the modification of the above solution,It worked for me, Thank you.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<?php
include('config.php');
$searchphrase = "adsa";
$table = "tenders";
$sql_search = "select * from " . $table . " where ";
$sql_search_fields = Array();
$sql = "SHOW COLUMNS FROM " . $table;
$rs = mysql_query($sql);
while ($r = mysql_fetch_array($rs)) {
$colum = $r[0];
$sql_search_fields[] = $colum . " like('%" . $searchphrase . "%')";
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs2 = mysql_query($sql_search);
$out = mysql_num_rows($rs2) . "\n";
echo "Number of search hits in $table " . $out."<br />";
while ($results = mysql_fetch_array($rs2)){
print $results[0]."<br />";
}
?>
</body>
</html>
I want to search in all fields from all tables of a MySQL database a given string, possibly using syntax as:
SELECT * FROM * WHERE * LIKE '%stuff%'
Is it possible to do something like this?
You could do an SQLDump of the database (and its data) then search that file.
If you have phpMyAdmin installed use its 'Search' feature.
Select your DB
Be sure you do have a DB selected (i.e. not a table, otherwise you'll get a completely different search dialog)
Click 'Search' tab
Choose the search term you want
Choose the tables to search
I have used this on up to 250 table/10GB databases (on a fast server) and the response time is nothing short of amazing.
You can peek into the information_schema schema. It has a list of all tables and all fields that are in a table. You can then run queries using the information that you have gotten from this table.
The tables involved are SCHEMATA, TABLES and COLUMNS. There are foreign keys such that you can build up exactly how the tables are created in a schema.
PHP function:
function searchAllDB($search){
global $mysqli;
$out = Array();
$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()){
$column = $r2[0];
$sql_search_fields[] = "`".$column."` like('%".$mysqli->real_escape_string($search)."%')";
}
$rs2->close();
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs3 = $mysqli->query($sql_search);
$out[$table] = $rs3->num_rows."\n";
if($rs3->num_rows > 0){
$rs3->close();
}
}
$rs->close();
}
return $out;
}
print_r(searchAllDB("search string"));
This is the simple way that's i know.
Select your DB in PHPMyAdmin, and go to the "Search" tab and write what you want to find and where you will searching for. Select all tables if you will search the words from all tables. Then "GO" and look the result.
If you are avoiding stored procedures like the plague, or are unable to do a mysql_dump due to permissions, or running into other various reasons.
I would suggest a three-step approach like this:
1) Where this query builds a bunch of queries as a result set.
# =================
# 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%'
;
Results should look like this:
2) You can then just Right Click and use the Copy Row (tab-separated)
3) Paste results in a new query window and run to your heart's content.
Detail: I exclude system schema's that you may not usually see in your workbench unless you have the option Show Metadata and Internal Schemas checked.
I did this to provide a quick way to ANALYZE an entire HOST or DB if needed or to run OPTIMIZE statements to support performance improvements.
I'm sure there are different ways you may go about doing this but here’s what works for 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';
Tested On MySQL Version: 5.6.23
WARNING: DO NOT RUN THIS IF:
You are concerned with causing Table-locks (keep an eye on your client-connections)
You are unsure about what you are doing.
You are trying to anger you DBA. (you may have people at your desk with the quickness.)
Cheers, Jay ;-]
It's been twelve years and no one posted an answer to the following question:
I want to search in all fields from all tables of a MySQL database for a given string
Anwsers include GUIs, vague ideas, syntax errors, procedures needing table names or prefixes and all sorts of contortions. Here's an actual, working, tested, simple to use answer building on multiple previous answers but also adding the primary key to the results.
DROP PROCEDURE IF EXISTS findAll;
DELIMITER $$
CREATE PROCEDURE findAll( IN `search` TEXT )
BEGIN
SET SESSION group_concat_max_len := ##max_allowed_packet;
SELECT GROUP_CONCAT(
"SELECT '", c1.TABLE_NAME, "' AS `table`, '", c1.COLUMN_NAME, "' AS `column`, ",
"CONCAT_WS(',', ", (SELECT GROUP_CONCAT(c2.column_name) FROM `information_schema`.`columns` c2 WHERE c1.TABLE_SCHEMA=c2.TABLE_SCHEMA AND c1.TABLE_NAME=c2.TABLE_NAME AND c2.COLUMN_KEY='PRI') ,") AS pri,",
c1.COLUMN_NAME, " AS value FROM ", c1.TABLE_NAME,
" WHERE `",c1.COLUMN_NAME,"` LIKE '%", search, "%'" SEPARATOR "\nUNION\n") AS col
INTO #sql
FROM information_schema.columns c1
WHERE c1.TABLE_SCHEMA = DATABASE();
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
That's it. You can now do CALL findAll('foobar');
Except not. You will run into two problems:
MySQL error 1436: Thread stack overrun
Prepared statement needs to be re-prepared.
Add the following two lines to /etc/mysql/mysql.conf.d/mysqld.cnf or wherever your cnf is or save them in a separate file and copy into the conf.d directory.
thread_stack = 2M
table_definition_cache = 5000
And yes, obviously this shouldn't be run on production because it's insecure and it'll tank your performance.
I also did my own mysql crawler to search some wordpress configuration, was unable to find it in both the interface and database, and database dumps were too heavy and unreadable. I must say I can't do without it now.
It works like the one from #Olivier, but it manages exotic database / table names and is LIKE-joker safe.
<?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++;
}
}
Running this script could output something like:
---------------------------------------------------
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
Using MySQL Workbench it's easy to select several tables and run a search for text in all those tables of the DB ;-)
This is the simplest query to retrive all Columns and Tables
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
All the tables or those with specific string in name could be searched via Search tab in phpMyAdmin.
Have Nice Query... \^.^/
I am use HeidiSQL is a useful and reliable tool designed for web developers using the popular MySQL server.
In HeidiSQL you can push shift + ctrl + f and you can find text on the server in all tables. This option is very usefully.
Although this question is old , here is how you can do it if you are using mysql workbench 6.3. ( Most likely it also works for other versions)
Right click your schema and "Search table data" , enter your value and hit "Start Search". Thats it.
Here is my solution for this
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;
MySQL Workbench
Here are some instructions.
Download and install MSQL Workbench.
https://www.mysql.com/products/workbench/
When installing, it might require you to install Visual Studio C++ Redistributable. You can get it here:
https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
x64: vc_redist.x64.exe (for 64 bit Windows)
When you open MySQL Workbench, you will have to enter your host name, user and password.
There is a Schemas tab on the side menu bar, click on the Schemas tab, then double click on a database to select the database you want to search.
Then go to menu Database - Search Data, and enter the text you are searching for, click on Start Search.
HeidiSql
Download and install HeidiSql
https://www.heidisql.com/download.php
Enter your hostname, user and password.
Hit Ctrl+Shift+F to search text.
This solution
a) is only MySQL, no other language needed, and
b) returns SQL results, ready for processing!
#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;
You could use
SHOW TABLES;
Then get the columns in those tables (in a loop) with
SHOW COLUMNS FROM table;
and then with that info create many many queries which you can also UNION if you need.
But this is extremely heavy on the database. Specially if you are doing a LIKE search.
To search a string in all tables in a database run the following command on CLI.
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString"
Or,
mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString" > searchingString.sql
I modified the PHP answer of Olivier a bit to:
print out the results in which the string was found
omit tables without results
also show output if column names match the search input
show total number of results
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;
}
I built on a previous answer and have this, some extra padding just to be able to conveniently join all the 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
First you run this, then paste in and run the result (no editing) and it will display all the table names and columns where the value is used.
Even if the following proposal should not be considered as a final solution you can achieve the goal by doing something like this:
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;
Please remember that:
Options: group_concat_max_len and limit 1000000 not always are needed, it will depends of your server/IDE configuration. Just in case I added them.
After executing this you will get a 3 column response: [table_name], [column_name], [matches]
Column 'matches' is the number of occurrences in the given table/column.
This query is very fast.
DISCLAIMER: It would be useful only for personal use, in other words please don't use it in a production system, because it is sensitive to SQL Injection attacks given that the search parameter is concatenated with other strings.
If you want to create a prod. ready function, then you will need to create a store procedure with a LOOP.
i got this to work. you just need to change the 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>";
I have done this using HeidiSQL.
It's not easy to find but by pressing Ctrl+Shift+F it displays the "table tools" dialogue. Then select what you want to search (Full database to single table) and enter the "Text to find" value and click "Find". I found it surprisingly fast (870MiB db in less than a minute)
In case 23 answers is not enough, here are 2 more... Depending on database structure and content, you may find one them to actually be a quick and simple solution.
For fans of shell one-liners, here is a long one (actually on 2 lines to use variables):
cmd='mysql -u Username -pYour_Password -D Your_Database' # <-- Adapt this
$cmd -s -e 'SHOW TABLES' | while read table; do echo "=== $table ==="; $cmd -B -s -e "SELECT * FROM $table" | grep 'Your_Search'; done
Or on multiple lines to make it more readable:
$cmd -s -e 'SHOW TABLES' \
| while read table; do
echo "=== $table ===";
$cmd -B -s -e "SELECT * FROM $table" \
| grep 'Your_Search';
done
-s (--silent) is to suppress the column name headers
-B (--batch) escapes special characters like newlines, so we get the whole record when using grep
And for Perl fans, this will let you use regular expressions:
# perl -MDBI -le '($db,$u,$p)=#ARGV; $dbh=DBI->connect("dbi:mysql:dbname=$db",$u,$p); foreach $table ($dbh->tables()) {print "$table\n"; foreach $r ($dbh->selectall_array("SELECT * FROM $table")) {$_=join("\t", #$r); print $_ if (/Your_Regex/);}}' Your_Database Username Your_Password
Which in a "real" Perl script could be something like this:
#!/usr/bin/perl
use strict;
use open qw(:std :utf8);
use DBI;
my $db_host = 'localhost';
my $db = 'Your_Database';
my $db_user = 'Username';
my $db_pass = 'Your_Password';
my $search = qr/Your_regex_Search/;
# https://metacpan.org/pod/DBD::mysql
my $dbh = DBI->connect( "dbi:mysql:dbname=$db;host=$db_host", $db_user, $db_pass,
{ mysql_enable_utf8mb4 => 1 }
) or die "Can't connect: $DBI::errstr\n";
foreach my $table ( $dbh->tables() ) {
my $sth = $dbh->prepare("SELECT * FROM $table")
or die "Can't prepare: ", $dbh->errstr;
$sth->execute
or die "Can't execute: ", $sth->errstr;
my #results;
while (my #row = $sth->fetchrow()) {
local $_ = join("\t", #row);
if ( /$search/ ) {
push #results, $_;
}
}
$sth->finish;
next unless #results;
print "*** TABLE $table :\n",
join("\n---------------\n", #results),
"\n" . "=" x 20 . "\n";
}
$dbh->disconnect;
I used Union to string together queries. Don't know if it's the most efficient way, but it works.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
There is a nice library for reading all 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
}
I don't know if this is only in the recent versions, but right clicking on the Tables option in the Navigator pane pops up an option called Search Table Data. This opens up a search box where you fill in the search string and hit search.
You do need to select the table you want to search in on the left pane. But if you hold down shift and select like 10 tables at a time, MySql can handle that and return results in seconds.
For anyone that is looking for better options! :)
If you are not using it on code level, you just want to check the information, you could export the entire database as SQL and then search on the text editor.