Search text in fields in every table of a MySQL database

前端 未结 24 1585
梦谈多话
梦谈多话 2020-11-22 06:23

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%\'
         


        
24条回答
  •  礼貌的吻别
    2020-11-22 06:56

    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.

    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
    

提交回复
热议问题