在MySQL数据库的每个表中搜索所有字段


Answers:


81

您可以浏览information_schema模式。它具有所有表和表中所有字段的列表。然后,您可以使用从该表获得的信息来运行查询。

涉及的表是SCHEMATA,TABLES和COLUMNS。有一些外键,使您可以准确地建立在模式中创建表的方式。


49
这不是我想要的答案,但我必须接受事实。:D谢谢
RSilva

1
这是正确的,但是@Dan Rather的回答也有所帮助,因为我正在浏览的数据库设置不明确,仅通过查看就无法确定列名或表的
确切含义

12
information_schema是数据库,而不是表。澄清一下要在哪个表中搜索information_schema就更好了!
CaptSaltyJack 2014年

3
MySql没有提供搜索所有表的方式对我来说很有趣。似乎是一个非常基本的选择
Kolob Canyon

@KolobCanyon MySQL确实提供了一个通过从db_name像“模式”中显示表
vladkras 2016年

442

您可以SQLDump对数据库(及其数据)进行处理,然后搜索该文件。


20
不要忘记,您可以对MySQLdump使用--extended-insert = FALSE标志,以使输出更具可读性。
Benubird

26
如果您想像我一样想知道铅笔的评论是关于什么的:snopes.com/business/genius/spacepen.asp
Jason Swett 2014年

2
这是搜索整个数据库的“标准”(事实上)方法。我喜欢mysqldump -T在指定目录的每个表中创建两个文件。然后grep <search> *,我在目录中返回tablename.txt或.sql文件。txt文件保存表的数据(制表符分隔,重命名为csv以在Excel中打开),而sql则保存表定义,您猜对了:SQL。这样,您可以搜索所有内容,并且很容易缩小数据的位置。但是,在某些环境中使用此方法可能会非常困难。堆栈溢出在这里非常有帮助。
乔尔·梅隆

如果您有大型SQL,或者有存档,则可以在服务器上的MC中直接打开它,然后查看
Vitaly Zdanevich 2015年

1
不错的建议!但是,如果db dump文件确实很大(我现在所处的状况:)),它将不起作用
Boban

207

如果您已安装phpMyAdmin,请使用其“搜索”功能。

  • 选择您的数据库
  • 确保您确实选择了一个数据库(即不是一个表,否则您将获得一个完全不同的搜索对话框)
  • 点击“搜索”标签
  • 选择您想要的搜索词
  • 选择要搜索的表

我已经在多达250个表/ 10GB的数据库上(在快速服务器上)使用了它,响应时间简直令人惊讶。


8
我们的数据库之一是92.7Gb,该选项很好用。绝佳解决方案
Tricky

5
我总是忘记phpMyAdmin可以做什么。这是一个很棒的工具!
2014年

1
非常快,对我的Magento数据库有帮助。在几秒钟内找到了我要查找的数据以及所有其他引用该数据的表的字段。
mtrueblood 2014年

1
MySQL Workbench也具有此功能:“数据库>>搜索表数据...”
matt wilkie 17/02/23

1
真好!现在您将如何替换phpmyadmin中搜索的字符串?
Pathros

46

PHP功能:

function searchAllDB($search){
    global $mysqli;

    $out = "";

    $sql = "show tables";
    $rs = $mysqli->query($sql);
    if($rs->num_rows > 0){
        while($r = $rs->fetch_array()){
            $table = $r[0];
            $out .= $table.";";
            $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('%".$search."%')";
                }
                $rs2->close();
            }
            $sql_search .= implode(" OR ", $sql_search_fields);
            $rs3 = $mysqli->query($sql_search);
            $out .= $rs3->num_rows."\n";
            if($rs3->num_rows > 0){
                $rs3->close();
            }
        }
        $rs->close();
    }

    return $out;
}

对于不认识的人,这是河粉。
Nandostyle

这样设置$mysqli$mysqli = new mysqli('localhost', 'root', 'hunter2', 'my_database');
亚当·泰勒

另外,我强烈建议更换$colum"`$colum`"让那些保留字的字段不会产生问题
亚当泰勒


12

如果您避免stored procedures像瘟疫一样,或者mysql_dump由于权限原因而无法执行操作,或者遇到其他各种原因。

我建议采用以下三步方法:

1)该查询将结果集构建为一堆查询。

# =================
# 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%'
;

结果应如下所示:

将这些结果复制到另一个查询窗口

2)然后就可以Right Click使用Copy Row (tab-separated)

在此处输入图片说明

3)将结果粘贴到新的查询窗口中,然后运行到您的心脏。

详细信息:除非您Show Metadata and Internal Schemas选中了该选项,否则我排除了您通常不会在工作台中看到的系统架构。

我这样做是为了在需要时提供一种快速访问ANALYZE整个HOST或DB的方法,或者提供运行OPTIMIZE语句以支持性能改进的方法。

我敢肯定,您可以采取不同的方式来做到这一点,但这对我有用:

-- ========================================== 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';

在MySQL版本上测试:5.6.23

警告:如果以下情况,请勿运行:

  1. 您担心引起表锁(注意客户端连接)
  2. 您不确定自己在做什么。

  3. 您正试图激怒您的DBA。(您可能很快就会有人在您的办公桌旁。)

干杯,周杰伦;-]


1
绝对不是您想在实时数据库上运行的东西,但对某些调试任务很有帮助。但是,如果列类型不与字符串进行比较,则此操作将失败。即一个int列。
Michael Thessel '17

很好,我添加了三种选择来搜索Blob,Chars或Int。这只是一个概括,应始终谨慎使用。就像您提到的那样,从未在PRODUCTION上执行过,这通常是使您解雇“在Internet上查找脚本并不理解它们,但仍在运行它们的原因”,但是,这就是人们学习困难方法的方式。
JayRizzo

8

我还用自己的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

1
我收到此错误:致命错误:消息为'SQLSTATE [42000]的未捕获异常'PDOException':语法错误或访问冲突:1064 SQL语法有错误;检查与您的MySQL服务器版本对应的手册以获取正确的语法,以在'key LIKE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('180well *','\\','\\\\')),'% ','在第1行'
LLBBL

6

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

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

所有表或名称中具有特定字符串的表都可以通过phpMyAdmin中的“搜索”选项卡进行搜索。

查询很好... \ ^。^ /


20
值又如何呢?
themhz 2013年


6

尽管这个问题很旧,但是如果您使用的是mysql workbench 6.3,则可以使用此方法。(最有可能也适用于其他版本)

右键单击您的架构和“搜索表数据”,输入值,然后单击“开始搜索”。而已。


6

这是我的解决方案

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
当我运行时CALL findAll('tbl_test','abb'),我错过了此错误:#1267-操作'='的排序规则(utf8_general_ci,IMPLICIT)和(utf8_unicode_ci,IMPLICIT)的非法混合使用,您可以解决吗?谢谢!
达沃兹2012年

6

这就是我所知道的简单方法。在PHPMyAdmin中选择您的数据库,然后转到“搜索”选项卡,写下您要查找的内容以及将在何处搜索。如果要搜索所有表中的单词,请选择所有表。然后“转到”并查看结果。我想从我的Wordpress数据库中找到VCD(后门)一词以进行删除


5

我正在使用HeidiSQL是一个有用且可靠的工具,专为使用流行的MySQL服务器的Web开发人员设计。

在HeidiSQL中,您可以按shift + ctrl + f,并且可以在服务器上的所有表中找到文本。此选项非常有用。


+1似乎做得很好,是一种有用的工具,可以节省其他一些答案中所涉及的工作。另外值得一提的是它可以让你选择哪个数据库(收费)进行查询。
史蒂夫钱伯斯

3

你可以用

SHOW TABLES;

然后使用以下命令获取这些表中的列(循环)

SHOW COLUMNS FROM table;

然后使用该信息创建许多查询,如果需要,也可以使用UNION。

但这在数据库上非常繁重。特别是如果您正在执行LIKE搜索。


SHOW TABLES FROM <db_name>更精确
vladkras

3

此解决方案
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;

对于这类解决方案,通常将它们添加到phpfiddler会很好,这样人们就可以看看甚至对您的解决方案发表评论。:)
pal4life 2014年

#1243 - Unknown prepared statement handler (stmt) given to EXECUTE当我在Phpmyadmin中运行您的查询以在整个数据库中进行搜索时,我得到了错误
Vicky Dev

@VickyDev我知道距您提出问题已经一年多了。抱歉。不过:我认为您的脚本中有些其他问题,因为在EXECUTE上方的行中声明了stmt。您正在使用哪个版本的MySQL?
Chonez

2

我将Olivier的PHP答案修改为:

  • 打印出找到字符串的结果
  • 省略没有结果的表
  • 如果列名称与搜索输入匹配,则还显示输出
  • 显示结果总数

    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

我以先前的答案为基础,并做了一些额外的填充,以便能够方便地加入所有输出:

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

首先运行此命令,然后粘贴并运行结果(不编辑),它将显示所有使用该值的表名和列。


1
对列值进行四次检查不是最简单的方法。您可以/应该WHERE NOT A.TABLE_SCHEMA IN ('mysql', 'innodb', 'performance_schema', 'information_schema'),甚至更好,执行它,检查使用的模式,并在何处设置使用的模式,而不是排除所有其他模式。
bradbury9

1

我有这个工作。您只需要更改变量

$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

我已经使用HeidiSQL做到了。这并不容易找到,但是通过按Ctrl + Shift + F可以显示“表格工具”对话框。然后选择要搜索的内容(将整个数据库存储到单个表中)并输入“要查找的文本”值,然后单击“查找”。我发现它出奇的快(不到一分钟就达到了870MiB db)


0

我用Union将查询串在一起。不知道这是否是最有效的方法,但是它有效。

SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';

这个答案的问题是,表的数量可变且未知数
bradbury9

0

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

我不知道这是只在最近的版本,但在右键单击Tables在选项Navigator面板弹出称为一个选项Search Table Data。这将打开一个搜索框,您可以在其中填写搜索字符串并点击搜索。

您确实需要在左窗格中选择要搜索的表。但是,如果您按住shift键并一次选择10张表,则MySql可以处理该问题并在几秒钟内返回结果。

对于任何正在寻找更好选择的人!:)


您正在使用什么应用程序进行所有这些操作?
乔恩·施耐德

他正在使用导航器应用程序。
Damir Olejar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.