特定の文字列をMySQLデータベース全体で検索する方法


19

特定の文字列を見つけるためにデータベーステーブル全体(行と列)を検索することは可能ですか?

私は約35個のテーブルを持つAという名前のデータベースを持っていますが、「hello」という名前の文字列を検索する必要があり、この文字列がどのテーブルに保存されているのかわかりません。それは可能ですか?

MySQLを使用する

私はLinux管理者であり、データベースに精通していません。クエリを説明することができれば本当に役立ちます。


1
こちらをご覧ください:stackoverflow.com/a/5350405/330315
a_horse_with_no_name

回答:



7

2012年7月にこの投稿を書きました

mysql dbのすべてのテーブルとフィールドのテキストを検索して置換するクエリ

テーブルinformation_schema.columnsを使用して、すべてのCHAR、VARCHAR、およびTEXTフィールドを取得し、テキストREPLACEを実行します。

私の古いリンクを見て、そのパラダイムを使用して検索してください。

例として、これはすべてのテーブルの各テキスト列に対して個別の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;

巨大な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,''';')

SHOULD:名前にスペースが含まれるテーブルに対して、以下に示す2つのバックティックを追加します。

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

このソリューションは非常にうまくいきました!最初のクエリを1行ずつ環境変数に手動でコピーする必要がありますか?mysqlセッション内でクエリを貼り付けて実行できましたが、そのクエリをファイルに貼り付けることもできますか?
ジョンT

@JohnT IIは、回答を垂直方向にスクロールする必要がないように、行ごとに実行します。最も簡単な方法を使用できます。
RolandoMySQLDBA

2

SQLクエリの構築を必要としない別のアプローチを採用して、データベース(MySQLを含む)をgrepし、「名前」内の「fred」の単純な「fred customer.name」タイプ検索の両方をサポートする無料のオープンソースコマンドラインツールとしてCRGREPを開発しました "customer"テーブルの列を、 "fr?d * .author"などのより複雑なパターンマッチングに変換して、すべてのテーブルのすべての "author"列に対するパターンマッチングを行います。


2

RolandoMySQLDBAの回答基に構築し、クエリを使用PREPAREしてEXECUTEを実行することにより、探している値に一致するすべてのテーブルからすべての列を一度に返すことができます

-- 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を渡すユーザー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 / rootMySQLの資格情報(または使用~/.my.cnf)、db_nameデータベース名へとfooあなたの検索テキストの。パラメータは--skip-extended-insertmysqldump各クエリを別々の行に表示します。のパラメーター--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

Oracleデータベース用のplsqlに実装されたあなたの質問に対するシンプルなテンプレートソリューションに焦点を当てています。MySQLでカスタマイズし、シンプルスローグーグルであると思います。必要なのは、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

このトリックを1行のコードで使用する

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

column_name:検索するすべての列名を入力します。

table_name:検索するすべてのテーブル名を入力します。


これは非常に小さなデータベースでは実用的かもしれません-数百のテーブルと数千の列にまたがって値を見つけようとしている場合はそれほどではありません。元の質問の「データベース全体」という表現に基づいて、これはDB内のすべてのテーブルを処理するものと想定しています。
RDFozz

0

MySQL Workbenchを使用している場合は、データベーススキーマを右クリックして[テーブルデータの検索...]を選択し、フォームに入力します。これにより、データベース全体が検索されます。結果が表示されたら(または表示されたら)、矢印をクリックして展開します。スキーマ、テーブル、主キーデータ、列名、検索に一致する実際のデータが表示されます。
ヒント:何も表示されない場合は、検索範囲を広げてみてください。
これはchar、テキスト(、varcharおよびtext)データ型を検索する場合にのみ本当に役立つことに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.