364

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?

2

29 Answers 29

492

You could do an SQLDump of the database (and its data) then search that file.

10
  • 27
    Don't forget you can use --extended-insert=FALSE flag for mysqldump to make the output more readable.
    – Benubird
    Commented Jan 24, 2013 at 10:30
  • 30
    In case you're wondering, like I was, what the pencil comment is about: snopes.com/business/genius/spacepen.asp Commented Aug 1, 2014 at 22:11
  • 4
    This is the "standard" (de facto) way to search entire DBs. I like mysqldump -T which creates two files per table in a specified directory. I then grep <search> * in the dir, and what's returned is the tablename.txt or .sql file. The txt file holds the data for the table (tab delimited, rename to csv to open in Excel), and the sql holds the table definition in, you guessed it: SQL. This way you're searching everything and it's easy to narrow down where your data is. This method can be quite difficult to get working in certain environments though. Stack Overflow is very helpful here. Commented Jan 14, 2015 at 17:37
  • 4
    Nice suggestion! But, it will not work if the db dump file is really big (situation that I am having now :) )
    – Bob
    Commented May 31, 2017 at 12:32
  • 1
    If your database dump is huge and has very long lines, grep will be slow. For example I have a file that's 85GB and its longest line is 3694931. In this case you can use "wc -L" to find the longest line-length and use the "sift" program (sift-tool.org - downloads as a single executable) to search much faster. If the longest line-length is greater than 2M then you have to use the --blocksize option with sift, like "sift --blocksize=4M searchstring mydump.sql"
    – royappa
    Commented Sep 19, 2017 at 5:57
245

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.

8
  • 8
    One of our databases is 92.7Gb and this option worked just fine. Great solution
    – Tricky
    Commented Nov 25, 2013 at 14:59
  • 6
    I always forget what all phpMyAdmin can do. It's a great tool!
    – Ville
    Commented Jan 8, 2014 at 20:07
  • 1
    Extremely fast, and helpful in my Magento db. Found the field for the data I was looking for in a couple of seconds, and also all the other tables that were referencing it.
    – mtrueblood
    Commented Jul 29, 2014 at 20:08
  • 2
    MySQL Workbench has this feature too: "Database >> Search Table Data..." Commented Feb 23, 2017 at 17:09
  • 1
    Remember to use the % symbol as a wildcard on either side of a string to find any rows containing what you're looking for. Commented Apr 12, 2017 at 14:40
87

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.

9
  • 62
    this is not the answer that I wanted, but I must accept the truth. :D Thank you
    – RSilva
    Commented Mar 12, 2009 at 17:49
  • 1
    This is correct, but @Dan Rather's answer helped too, because the db I was looking through was setup obscurely and I couldn't figure out what the column name or table would be for sure just by looking...
    – DrCord
    Commented Jan 1, 2014 at 19:14
  • 15
    information_schema is a database, not a table. Some clarification on which table to search within information_schema would be good! Commented Aug 7, 2014 at 21:20
  • 5
    It's kind of hilarious to me that MySql provided no way of searching all tables. Seems like a pretty rudimentary option Commented Sep 21, 2016 at 21:44
  • @KolobCanyon MySQL does provide an option to do it via SHOW TABLES FROM db_name LIKE 'pattern'
    – vladkras
    Commented Nov 20, 2016 at 9:52
52

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"));
5
  • This is pho, for those who may not know. Commented Nov 22, 2019 at 5:41
  • 2
    Set $mysqli like this: $mysqli = new mysqli('localhost', 'root', 'hunter2', 'my_database'); Commented May 8, 2020 at 19:32
  • 2
    Also, I highly recommend replacing $colum with "`$colum`" so that fields that are reserved words won't cause problems Commented May 8, 2020 at 19:32
  • will it not cause sql injection in line: like('%".$search."%')" because the search string is directly put in the query? Commented Mar 5, 2021 at 7:13
  • I think this is purely technical implementation may be for debugging database in some how, Thanks for the solution. Commented Jul 8 at 8:10
20

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.I Want to find the word VCD (backdoor) from my Wordpress DB for deleting

18

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:

Copy these results into another query window

2) You can then just Right Click and use the Copy Row (tab-separated)

enter image description here

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:

  1. You are concerned with causing Table-locks (keep an eye on your client-connections)
  2. You are unsure about what you are doing.

  3. You are trying to anger you DBA. (you may have people at your desk with the quickness.)

Cheers, Jay ;-]

3
  • 1
    Definitely not something you want to run on a live db but helpful for certain debugging tasks. This fails though if the column type doesn't compare against a string. I.e. an int column. Commented Nov 9, 2017 at 0:44
  • Great point, I added three alternatives to search thru blobs, chars, or ints. This is just a Generalization and should ALWAYS be used with CAUTION. NEVER on PRODUCTION as you mentioned as, that is usually what gets you fired "Finding scripts on the internet and not understanding them, but yet still running them" but, hey that is how people learn the hard way.
    – JayRizzo
    Commented Nov 14, 2017 at 0:20
  • Imho this is the best answer. One should encapsulate the table & column names around backticks for those names that could be SQL keywords.
    – khelkun
    Commented Nov 22, 2021 at 12:04
16

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:

  1. MySQL error 1436: Thread stack overrun
  2. 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.

3
  • "it's insecure and it'll tank your performance" - how exactly is this meant? What if no one is currently using the application? Is it fine then? What are the exact security problems (so I can understand it better)?
    – user753676
    Commented Jan 15, 2022 at 23:18
  • 1
    It can be deployed on the production MySQL just make sure untrusted users can't access findAll. Trusted and knowledgeable (for example, they need to know "there's no problem with putting a huge load on the server right now") users running it is fine, it's just a very massive SELECT, it's not like it's deleting data or such. How massive? It does investigate every record in every table and most often does it unindexed. But untrusted user input can wreak any havoc as we are turning input into a statement and run it. There's no escaping mechanism at all.
    – chx
    Commented Jan 15, 2022 at 23:55
  • Understood, thanks for the clarification.
    – user753676
    Commented Jan 16, 2022 at 8:28
10

Using MySQL Workbench it's easy to select several tables and run a search for text in all those tables of the DB ;-)

1
  • 1
    Thank you! First time I've used workbench. Was fairly intuitive, it pointed me to the table I needed and I was able to locate it from there.
    – joshmiller
    Commented Sep 25, 2019 at 13:24
9

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: [email protected]
        numero_client_compta: C05135
        nom_client: Tiemblo
        adresse_facturation_1: 151, My Street
        adresse_facturation_2: 
        ville_facturation: Nantes
        code_postal_facturation: 44300
        pays_facturation: FR
        numero_tva_client: 
        zone_geographique: UE
        prenom_client: Alain
        commentaires: 
        nom_societe: 
        email_facturation: [email protected]
1
  • 1
    I get this error: Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key LIKE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('180well*', '\\', '\\\\'), '%',' at line 1'
    – LLBBL
    Commented Sep 7, 2015 at 20:55
8

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.

1
  • +1 Seems to do the job well and is a useful tool that saves the faff involved in some of the other answers. Also worth noting that it allows you to choose which database(s) to search in. Commented Aug 5, 2016 at 9:13
7

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.

enter image description here

HeidiSql

Download and install HeidiSql https://www.heidisql.com/download.php

Enter your hostname, user and password.

Hit Ctrl+Shift+F to search text.

enter image description here

1
  • 1
    Thank you for sharing this great tool : HeidiSql
    – Peacefull
    Commented Aug 19, 2020 at 8:21
6

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... \^.^/

1
  • 28
    and how about the values?
    – themhz
    Commented Nov 7, 2013 at 18:27
6

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.

6

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;
1
  • 1
    when I run CALL findAll('tbl_test','abb'), I miss this error: #1267 - Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '=' Can you fix it? Thanks!
    – Davuz
    Commented May 25, 2012 at 6:00
5

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
4

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;
3
  • For these kinds of solution usually adding them to phpfiddler would be nice so folks can take a look at and even comment on your solution. :)
    – pal4life
    Commented Jun 19, 2014 at 20:16
  • 2
    I am getting error #1243 - Unknown prepared statement handler (stmt) given to EXECUTE when I run your query in Phpmyadmin for searching in whole database
    – Vicky Dev
    Commented May 3, 2016 at 6:24
  • @VickyDev I know it's been more than a year since your question. Sorry. Nevertheless: I think something else is wrong in your script since stmt is declared in the row above EXECUTE. Which version of MySQL are you using?
    – Chonez
    Commented Aug 26, 2017 at 13:07
3

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.

1
  • SHOW TABLES FROM <db_name> is more precise
    – vladkras
    Commented Nov 20, 2016 at 9:49
2

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;
    }
    
1
  • Hello! Please, could you help me? I am finding Call to undefined method mysqli_result::fetch_all(). Thank you. Commented Jun 9, 2022 at 4:30
2

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.

1
  • 1
    Four checks on a column value is not the most simple way. You could/should WHERE NOT A.TABLE_SCHEMA IN ('mysql', 'innodb', 'performance_schema', 'information_schema') or even better, execute it, check the schemas used, and set the used schema in the where instead excluding all the others.
    – Cleptus
    Commented Aug 10, 2018 at 10:35
2

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:

  1. 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.

  2. After executing this you will get a 3 column response: [table_name], [column_name], [matches]

  3. Column 'matches' is the number of occurrences in the given table/column.

  4. 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.

1

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>";
1

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)

1

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;
1

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.

1
1

Using the best answer from above and making a minor adjustment so that it can be used on production by cleaning itself up. (would have just posted it as a comment, but the character limit prevents that)

  1. added backticks to the query for a bug I encountered using it
  2. added drop procedure to the end to delete the newly created procedure to clean up
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' LIMIT 1) ,") 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 ;

CALL findAll('search string here');

DROP PROCEDURE IF EXISTS findAll;
1
  • You could just edit my answer to add more backticks and delete this. (Please don't add the DROP PROCEDURE -- the problem with deploying to production is not a leftover procedure as my comments explain.)
    – chx
    Commented Nov 26, 2023 at 15:24
0

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%';
1
  • The problem with this answer is that there is a variable and unkown number of tables
    – Cleptus
    Commented Aug 10, 2018 at 10:38
0

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

}
0

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! :)

2
  • What application are you doing all of this in? Commented Jul 10, 2019 at 20:50
  • He is using the Navigator application.
    – 3xCh1_23
    Commented Feb 21, 2020 at 18:01
-1

Search with Single condition:

Syntax: 
   SELECT * FROM TabeName where ColumnName = 'value'
   SELECT * FROM TabeName where ImageId = 'm-t0627-02620-00266'

Search with more than one condition

   Syntax: 
   SELECT * FROM TabeName where ColumnName = value and ColumnName = 'value'
   SELECT * FROM RecordCorrections.OremEntry where DbId = 2442 and ImageId = 'm-t0627-02620-00266';

Note: consider DbId as Int and ImageId as String value

Not the answer you're looking for? Browse other questions tagged or ask your own question.