我想从一个MySQL数据库的所有表的所有字段搜索一个给定的字符串,可能使用语法为:

SELECT * FROM * WHERE * LIKE '%stuff%'

有可能做这样的事情吗?


当前回答

有一个很好的图书馆可以阅读所有表格,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

}

其他回答

使用MySQL Workbench可以很容易地选择几个表,并在所有这些数据库表中搜索文本;-)

我也做了我自己的mysql爬虫来搜索一些wordpress配置,在界面和数据库中都无法找到它,数据库转储太沉重和不可读。我得说我现在不能没有它。

它的工作原理类似于@Olivier,但它管理外来的数据库/表名,并且是像小丑一样安全。

<?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++;
    }
}

运行这个脚本可以输出如下内容:

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

如果23个答案还不够,这里还有2个……根据数据库结构和内容,您可能会发现其中一个实际上是快速而简单的解决方案。

对于shell一行程序的爱好者,这里有一个很长的程序(实际上只有2行,使用变量):

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

或多行,使其更具可读性:

$cmd -s -e 'SHOW TABLES' \
| while read table; do
    echo "=== $table ===";
    $cmd -B -s -e "SELECT * FROM $table" \
    | grep 'Your_Search';
  done

-s(——silent)用于屏蔽列名标头 -B(——batch)转义像换行符这样的特殊字符,所以我们在使用grep时获得整个记录

对于Perl爱好者来说,这将允许您使用正则表达式:

# 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

在“真正的”Perl脚本中可能是这样的:

#!/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;

12年过去了,还没有人发帖回答下面这个问题:

我想从MySQL数据库的所有表中搜索给定字符串的所有字段

答案包括gui、模糊的概念、语法错误、需要表名或前缀的过程以及各种扭曲。下面是一个实际的、有效的、经过测试的、简单易用的答案,它建立在多个先前的答案的基础上,同时还将主键添加到结果中。

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 ;

就是这样。你现在可以调用findAll('foobar');

不除外。你会遇到两个问题:

MySQL错误1436:线程堆栈溢出 准备好的语句需要重新准备。

将以下两行添加到/etc/mysql/mysql.conf.d/mysqld.cnf或任何你的cnf所在的地方,或者将它们保存在一个单独的文件中并复制到conf.d目录。

thread_stack            = 2M
table_definition_cache  = 5000

是的,显然这不应该在生产环境中运行,因为它不安全,而且会降低您的性能。

这是检索所有列和表的最简单的查询

SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'

在phpMyAdmin中,可以通过搜索选项卡搜索所有表或名称中有特定字符串的表。

有良好的查询…\ ^ ^ /