【问题标题】:Search text in fields in every table of a MySQL database在 MySQL 数据库的每个表的字段中搜索文本
【发布时间】:2010-10-12 23:26:56
【问题描述】:

我想在 MySQL 数据库的所有表中搜索给定字符串的所有字段,可能使用如下语法:

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

有可能做这样的事情吗?

【问题讨论】:

标签: mysql


【解决方案1】:

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

【讨论】:

  • 别忘了你可以为 mysqldump 使用 --extended-insert=FALSE 标志来使输出更具可读性。
  • 如果您像我一样想知道铅笔评论是关于什么的:snopes.com/business/genius/spacepen.asp
  • 这是搜索整个数据库的“标准”(事实上)方式。我喜欢mysqldump -T,它在指定目录中为每个表创建两个文件。然后我在目录中grep <search> *,返回的是tablename.txt 或.sql 文件。 txt 文件保存表的数据(制表符分隔,重命名为 csv 以在 Excel 中打开),而 sql 保存表定义,您猜对了:SQL。通过这种方式,您可以搜索所有内容,并且可以轻松缩小数据的位置。但是,这种方法可能很难在某些环境中工作。 Stack Overflow 在这里很有帮助。
  • 好建议!但是,如果 db 转储文件真的很大(我现在的情况:))
  • 如果你的数据库转储很大并且行很长,grep 会很慢。例如,我有一个 85GB 的文件,最长的行是 3694931。在这种情况下,您可以使用“wc -L”查找最长的行长并使用“sift”程序(sift-tool.org - 下载为单个可执行文件) 搜索速度更快。如果最长的行长度大于 2M,那么您必须在 sift 中使用 --blocksize 选项,例如 "sift --blocksize=4M searchstring mydump.sql"
【解决方案2】:

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

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

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

【讨论】:

  • 我们的一个数据库是 92.7Gb,这个选项工作得很好。很好的解决方案
  • 我总是忘记 phpMyAdmin 能做什么。这是一个很棒的工具!
  • 非常快,对我的 Magento 数据库很有帮助。在几秒钟内找到了我正在寻找的数据的字段,以及引用它的所有其他表。
  • MySQL Workbench 也有这个功能:"数据库>>搜索表数据..."
  • 不错!现在你将如何替换 phpmyadmin 中搜索到的字符串?
【解决方案3】:

您可以查看information_schema 架构。它具有所有表和表中所有字段的列表。然后,您可以使用从该表中获得的信息运行查询。

涉及的表是 SCHEMATA、TABLES 和 COLUMNS。有外键,这样您就可以准确地构建表在模式中的创建方式。

【讨论】:

  • 这不是我想要的答案,但我必须接受事实。 :D 谢谢
  • 这是正确的,但@Dan 拉瑟的回答也有帮助,因为我正在查看的数据库设置不明确,我无法通过查看来确定列名或表是什么...
  • information_schema 是数据库,而不是表。澄清一下在information_schema 中搜索哪个表会很好!
  • MySql 没有提供搜索所有表的方法,这对我来说有点搞笑。似乎是一个非常基本的选择
  • @KolobCanyon MySQL 确实提供了一个通过SHOW TABLES FROM db_name LIKE 'pattern' 进行操作的选项
【解决方案4】:

PHP函数:

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

【讨论】:

  • 这是pho,可能不知道的人。
  • 这样设置$mysqli$mysqli = new mysqli('localhost', 'root', 'hunter2', 'my_database');
  • 另外,我强烈建议将$colum 替换为"`$colum`",这样保留字的字段就不会造成问题
  • 会不会因为直接在查询中放入搜索字符串而导致sql注入line:like('%".$search."%')"?
【解决方案5】:

如果您像瘟疫一样避免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 整个主机或数据库(如果需要)或运行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。 (您的办公桌上可能会有人快速。)

干杯,杰 ;-]

【讨论】:

  • 绝对不是您想在实时数据库上运行的东西,但对某些调试任务很有帮助。如果列类型不与字符串进行比较,这将失败。 IE。一个 int 列。
  • 好点,我添加了三种替代方法来搜索 blob、chars 或 int。这只是一个概括,应始终谨慎使用。永远不要像您提到的那样使用 PRODUCTION,这通常是您被解雇的原因“在互联网上查找脚本并且不理解它们,但仍然在运行它们”但是,嘿,这就是人们学习艰难的方式。
  • 恕我直言,这是最好的答案。对于那些可能是 SQL 关键字的名称,应该将表名和列名封装在反引号周围。
【解决方案6】:

这是我知道的简单方法。 在 PHPMyAdmin 中选择您的数据库,然后转到“搜索”选项卡并写下您想要查找的内容以及您将搜索的位置。如果要从所有表中搜索单词,请选择所有表。然后“GO”看看结果。

【讨论】:

    【解决方案7】:

    使用 MySQL Workbench,可以轻松选择多个表并在数据库的所有这些表中运行文本搜索;-)

    【讨论】:

    • 谢谢!我第一次使用工作台。相当直观,它把我指向了我需要的桌子,我可以从那里找到它。
    【解决方案8】:

    我也做了自己的mysql爬虫来搜索一些wordpress配置,在界面和数据库中都找不到,而且数据库转储太重且不可读。我必须说我现在离不开它。

    它的工作方式与 @Olivier 的类似,但它管理奇异的数据库/表名,并且是 LIKE-joker 安全的。

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

    【讨论】:

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

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

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

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

    有很好的查询... \^.^/

    【讨论】:

    • 值呢?
    【解决方案10】:

    虽然这个问题很老,但如果您使用的是 mysql workbench 6.3,这里是如何做到的。 (很可能它也适用于其他版本)

    右键单击您的架构和“搜索表数据”,输入您的值并点击“开始搜索”。就是这样。

    【讨论】:

      【解决方案11】:

      这是我的解决方案

      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;
      

      【讨论】:

      • 当我运行 CALL findAll('tbl_test','abb') 时,我错过了这个错误:#1267 - Illegal mix of collat​​ions (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '='你能修好它吗?谢谢!
      【解决方案12】:

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

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

      【讨论】:

      • +1 似乎做得很好,并且是一个有用的工具,可以节省涉及其他一些答案的麻烦。另外值得注意的是,它允许您选择要搜索的数据库。
      【解决方案13】:

      MySQL 工作台

      这里有一些说明。

      下载并安装 MSQL Workbench。

      https://www.mysql.com/products/workbench/

      安装时,可能需要您安装 Visual Studio C++ Redistributable。你可以在这里得到它:

      https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads

      x64: vc_redist.x64.exe(适用于 64 位 Windows)

      当您打开 MySQL Workbench 时,您必须输入您的主机名、用户名和密码。

      侧边菜单栏有一个Schemas选项卡,点击Schemas选项卡,然后双击一个数据库选择你要搜索的数据库。

      然后进入菜单数据库-搜索数据,输入你要搜索的文本,点击开始搜索。

      HeidiSql

      下载并安装 HeidiSql https://www.heidisql.com/download.php

      输入您的主机名、用户名和密码。

      按 Ctrl+Shift+F 搜索文本。

      【讨论】:

      • 感谢您分享这个伟大的工具:HeidiSql
      【解决方案14】:

      十二年没有人回答以下问题:

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

      Anwsers 包括 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 ;
      

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

      除非没有。你会遇到两个问题:

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

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

      thread_stack            = 2M
      table_definition_cache  = 5000
      

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

      【讨论】:

        【解决方案15】:

        你可以使用

        SHOW TABLES;
        

        然后使用

        获取这些表中的列(循环)
        SHOW COLUMNS FROM table;
        

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

        但这对数据库来说非常沉重。特别是如果您正在进行 LIKE 搜索。

        【讨论】:

        • SHOW TABLES FROM &lt;db_name&gt; 更精确
        【解决方案16】:

        这个解决方案
        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 会很好,因此人们可以查看甚至评论您的解决方案。 :)
        • 当我在 Phpmyadmin 中运行查询以在整个数据库中搜索时,我收到错误 #1243 - Unknown prepared statement handler (stmt) given to EXECUTE
        • @VickyDev 我知道你的问题已经一年多了。对不起。尽管如此:我认为您的脚本中还有其他问题,因为 stmt 在 EXECUTE 上方的行中声明。您使用的是哪个版本的 MySQL?
        【解决方案17】:

        我将 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;
          }
          

        【讨论】:

          【解决方案18】:

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

          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
          

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

          【讨论】:

          • 对一个列值进行四次检查并不是最简单的方法。您可以/应该 WHERE NOT A.TABLE_SCHEMA IN ('mysql', 'innodb', 'performance_schema', 'information_schema') 甚至更好,执行它,检查使用的模式,并将使用的模式设置在 where 而不是排除所有其他模式。
          【解决方案19】:

          即使不应将以下提案视为最终解决方案,您也可以通过执行以下操作来实现目标:

          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;
          

          请记住:

          1. 选项:group_concat_max_lenlimit 1000000 并不总是需要,这取决于您的服务器/IDE 配置。以防万一我添加了它们。

          2. 执行此操作后,您将获得 3 列响应:[table_name]、[column_name]、[matches]

          3. 列“匹配”是给定表/列中出现的次数。

          4. 这个查询非常快。

          免责声明:它仅对个人使用有用,换句话说,请不要在生产系统中使用它,因为它对 SQL 注入攻击很敏感,因为搜索参数与其他字符串连接。 如果你想创建一个产品。 ready 函数,那么您将需要创建一个带有 LOOP 的存储过程。

          【讨论】:

            【解决方案20】:

            我得到了这个工作。你只需要改变变量

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

            【讨论】:

              【解决方案21】:

              我已经使用 HeidiSQL 完成了这项工作。 它不容易找到,但按 Ctrl+Shift+F 会显示“表格工具”对话框。然后选择您要搜索的内容(完整数据库到单个表)并输入“要查找的文本”值并单击“查找”。我发现它速度惊人(不到一分钟 870MiB db)

              【讨论】:

                【解决方案22】:

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

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

                【讨论】:

                • 这个答案的问题是有一个变量和未知数量的表
                【解决方案23】:

                有一个不错的库可以读取所有表格,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
                
                }
                

                【讨论】:

                  【解决方案24】:

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

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

                  适合任何正在寻找更好选择的人! :)

                  【讨论】:

                  • 您在哪个应用程序中执行所有这些操作?
                  • 他正在使用 Navigator 应用程序。
                  【解决方案25】:

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

                  【讨论】:

                    【解决方案26】:

                    要在数据库的所有表中搜索字符串,请在 CLI 上运行以下命令。

                    mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString"
                    

                    或者,

                    mysqldump -u UserName --no-create-info --extended-insert=FALSE DBName -p | grep -i "searchingString" > searchingString.sql
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      相关资源
                      最近更新 更多