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

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

有可能做这样的事情吗?


当前回答

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

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

其他回答

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

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

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

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

即使下面的建议不应该被认为是最终的解决方案,你也可以通过这样做来实现目标:

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;

请记住:

选项:group_concat_max_len和limit 1000000并不总是必需的,这将取决于您的服务器/IDE配置。以防我加进去。 执行此命令后,您将得到一个3列响应:[table_name], [column_name], [matches] 列'matches'是给定表/列中出现的次数。 这个查询非常快。

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

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

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