如何在整个MySQL数据库中搜索特定字符串


19

是否有可能搜索整个数据库表(行和列)以找出特定的字符串。

我有一个约有35个表的名为A的数据库,我需要搜索名为“ hello”的字符串,但我不知道此字符串保存在哪个表上。可以吗?

使用MySQL

我是一名Linux管理员,我对数据库不熟悉,如果您还可以解释该查询,那将非常有帮助。


Answers:



7

早在2012年7月,我写了这篇文章

查询以查找和替换mysql数据库的所有表和字段中的文本

它使用表information_schema.columns提取每个CHAR,VARCHAR和TEXT字段并执行文本替换

请查看我的旧链接,并使用其范例进行搜索。

例如,这将为每个表中的每个文本列创建一个单独的SELECT。

SELECT
    CONCAT('SELECT ',QUOTE(db),',',QUOTE(tb),',',QUOTE(col),',COUNT(1) FieldHasIt
    FROM ',db,'.',tb,' WHERE \`',col,'\`=''',SearchString,''';') SearchSQL
FROM
(
    SELECT table_schema db,table_name tb,column_name col FROM information_schema.columns
    WHERE table_schema = 'mydb' AND
    (column_type LIKE 'char(%' OR column_type LIKE 'varchar(%' OR column_type LIKE '%text')
) A,(SELECT 'Hello' SearchString) B;

使用它创建一个Giant SQL文本文件。然后,执行该Giant SQL脚本:

SQL="SELECT CONCAT('SELECT ',QUOTE(db),',',QUOTE(tb),',',"
SQL="${SQL} QUOTE(col),',COUNT(1) FieldHasIt FROM ',db,'.',tb,'"
SQL="${SQL} WHERE \`',col,'\`=''',SearchString,''';') SearchSQL FROM"
SQL="${SQL} (SELECT table_schema db,table_name tb,column_name col FROM"
SQL="${SQL} information_schema.columns WHERE table_schema='store_qa'"
SQL="${SQL} AND (column_type LIKE 'char(%' OR column_type LIKE 'varchar(%'"
SQL="${SQL} OR column_type LIKE '%text')) A,(SELECT 'Hello' SearchString) B;"

mysql -uroot -p... -ANe"${SQL}" > MegaSearch.sql
mysql -uroot -p... -AN < MegaSearch.sql > MegaSearchResults.txt
RESULTS_FOUND=`grep -c "1$" < MegaSearchResults.txt`
echo ${RESULTS_FOUND}
if [ ${RESULTS_FOUND} -gt 0 ] ; then grep "1$" < MegaSearchResults.txt ; fi

输出告诉您数据出现的数据库,表和列。

试试看 !!!。

编辑:

CONCAT('SELECT ',QUOTE(db),',',QUOTE(tb),',',QUOTE(col),',COUNT(1) FieldHasIt
        FROM ',db,'.',tb,' WHERE \`',col,'\`=''',SearchString,''';')

应该:对于名称中带有空格的表,添加下面显示的两个反勾号。

db,'.`',tb,'`',' WHERE

这个解决方案效果很好!是否有必要手动将初始查询逐行复制到环境变量中?我能够在mysql会话中粘贴并运行查询,但是当然也可以将该查询粘贴到文件中吗?
约翰T

@JohnT II逐行执行,以避免垂直滚动我的答案。您可以执行最简单的任何一种方法。
RolandoMySQLDBA

2

采用另一种不需要构建SQL查询的方法,我开发了CRGREP作为免费的开源命令行工具,该工具将grep数据库(包括MySQL)并支持简单的“ fred customer.name”类型在“ name”中搜索“ fred” “客户”表中的“”列可进行更复杂的模式匹配,例如“ fr?d * .author”,用于对所有表中的所有“作者”列进行模式匹配。


2

通过构建RolandoMySQLDBA的答案并使用PREPAREEXECUTE运行查询,可以一次返回所有表中与您要查找的所有值匹配的所有列。

-- Your values
SET @table_schema = 'your_table_name';
SET @condition = "LIKE '%your string to search%'";
SET @column_types_regexp = '^((var)?char|(var)?binary|blob|text|enum|set)\\(';

-- Reset @sql_query in case it was used previously
SET @sql_query = '';

-- Build query for each table and merge with previous queries with UNION
SELECT
    -- Use `DISTINCT IF(QUERYBUILDING, NULL, NULL)`
    -- to only select a single null value
    -- instead of selecting the query over and over again as it's built
    DISTINCT IF(@sql_query := CONCAT(
        IF(LENGTH(@sql_query), CONCAT(@sql_query, " UNION "), ""),
        'SELECT ',
            QUOTE(CONCAT('`', `table_name`, '`.`', `column_name`, '`')), ' AS `column`, ',
            'COUNT(*) AS `occurrences` ',
        'FROM `', `table_schema`, '`.`', `table_name`, '` ',
        'WHERE `', `column_name`, '` ', @condition
    ), NULL, NULL) `query`
FROM (
    SELECT
        `table_schema`,
        `table_name`,
        `column_name`
    FROM `information_schema`.`columns`
    WHERE `table_schema` = @table_schema
    AND `column_type` REGEXP @column_types_regexp
) `results`;
select @sql_query;

-- Only return results with at least one occurrence
SET @sql_query = CONCAT("SELECT * FROM (", @sql_query, ") `results` WHERE `occurrences` > 0");

-- Run built query
PREPARE statement FROM @sql_query;
EXECUTE statement;
DEALLOCATE PREPARE statement;

1

如果可以使用bash-这是一个脚本:它需要在数据库上具有用户dbread和pass dbread的权限。

#!/bin/bash
IFS='
'
DBUSER=dbread
DBPASS=dbread
echo -n "Which database do you want to search in (press 0 to see all databases): " 
read DB
echo -n "Which string do you want to search: " 
read SEARCHSTRING
for i in `mysql $DB -u$DBUSER -p$DBPASS -e "show tables" | grep -v \`mysql $DB -u$DBUSER -p$DBPASS -e "show tables" | head -1\``
do
for k in `mysql $DB -u$DBUSER -p$DBPASS -e "desc $i" | grep -v \`mysql $DB -u$DBUSER -p$DBPASS -e "desc $i" | head -1\` | grep -v int | awk '{print $1}'`
do
if [ `mysql $DB -u$DBUSER -p$DBPASS -e "Select * from $i where $k='$SEARCHSTRING'" | wc -l` -gt 1 ]
then
echo " Your searchstring was found in table $i, column $k"
fi
done
done

如果有人想要解释:http : //infofreund.de/?p=1670


1

如果您是Linux管理员,则应该熟悉命令行,因此该命令非常方便:

$ mysqldump -u root -proot --skip-extended-insert db_name | grep --color=auto -w foo

root/ 更改root为mysql凭据(或使用~/.my.cnf),db_name更改为数据库名称和foo搜索文本。参数--skip-extended-insertfor mysqldump将在单独的行中显示每个查询。参数--color=autogrep将突出你的字符串,-w将匹配整个单词。


0

您可以访问phpMyAdmin吗?它具有每个数据库的搜索功能。

或对(更改dbname)的结果使用您选择的脚本:

$string = 'mysqldump --compact --skip-extended-insert -u ' . $db_user . ' -p' . $db_password . ' dbname 2>&1 | grep "particular string" 2>&1';
$result = shell_exec ( $string );

0

我专注于针对您的问题的简单模板解决方案,该问题在plsql for Oracle中实现数据库实现,我希望在MySql上对其进行自定义,成为简单的Google搜索。您需要做的是研究MySql上的信息架构并替换一些表名和列。

在脚本中: ALL_TAB_COLUMNS是一个包含所有表列的信息架构表 'VARCHAR2','NVARCHAR2','NCHAR','CHAR'指的是Oracle中的字符串列类型,您必须将它们替换为与MySql
%hello%等效的类型名称是搜索关键字,用任何字符串替换它。

结果将是一些或许多sql脚本(基于表的列类型),运行它们将得出答案。
另外,性能和时间消耗也将是另一回事。
我希望这会有用

SELECT 
'SELECT ' || ALL_TAB_COLUMNS.COLUMN_NAME  || ' AS RESULT_FOUND, ' 
|| '''' || ALL_TAB_COLUMNS.TABLE_NAME ||''''|| ' AS TABLE_NAME, '
|| '''' || ALL_TAB_COLUMNS.COLUMN_NAME ||''''|| ' AS COLUMN_NAME '
|| 'FROM ' || ALL_TAB_COLUMNS.OWNER ||'.'||ALL_TAB_COLUMNS.TABLE_NAME  
|| ' WHERE ' || ALL_TAB_COLUMNS.COLUMN_NAME || ' LIKE ''%hello%''' || ';'
FROM ALL_TAB_COLUMNS 
WHERE 
ALL_TAB_COLUMNS.OWNER = 'SCOTT'
AND 
ALL_TAB_COLUMNS.DATA_TYPE IN ('VARCHAR2','NVARCHAR2','NCHAR','CHAR')

0

ridona有一个不错的图书馆,可以读取所有表格

$database = new ridona\Database('mysql:dbname=database_name;host=127.0.0.1', 'db_user','db_pass');

foreach ($database->tables(['table_name1','table_name2'])->by_entire() as $row) {

  do...

}

0

使用此技巧与一行代码

SELECT * FROM `table_name1`,`table_name2` 
WHERE '$data' IN (`column_name1`,`column_name2`,`column_name3`,`column_name4`);

column_name:键入要在其中搜索的所有列名称。

table_name:键入您要在其中搜索的所有表名。


这在很小的数据库中可能是实用的-如果要在数百个表和数千个列中定位值,则情况会更糟。基于原始问题中的“整个数据库”一词,我假设这应该处理数据库中的所有表。
RDFozz '18年

0

如果您使用的是MySQL Workbench,请右键单击数据库架构,然后选择“搜索表数据...”,然后填写表格。这将搜索整个数据库。当(或如果)结果出现时,单击箭头以展开。它将显示架构,表,主键数据,列名以及与您的搜索匹配的实际数据。
提示:如果什么都没有发生,请尝试扩大搜索范围。
请注意,这只是用于搜索文本非常有用(charvarchartext)数据类型。

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.