我想从一个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

}

其他回答

你可以用

SHOW TABLES;

然后获取这些表中的列(在循环中)

SHOW COLUMNS FROM table;

然后用这些信息创建很多很多的查询,如果你需要的话,你也可以UNION这些查询。

但这对数据库的影响非常大。特别是如果你在做LIKE搜索。

这个解决方案 a)只有MySQL,不需要其他语言,并且 b)返回SQL结果,准备处理!

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

如果你安装了phpMyAdmin,使用它的“搜索”功能。

选择您的数据库 确保你有一个DB选择(即不是一个表,否则你会得到一个完全不同的搜索对话框) 点击“搜索”标签 选择您想要的搜索词 选择要搜索的表

我在250个表/10GB的数据库上使用过这个功能(在一个快速的服务器上),响应时间非常惊人。

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

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

如果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;