Cara mencari seluruh database MySQL untuk string tertentu

19

apakah mungkin untuk mencari seluruh tabel database (baris dan kolom) untuk mengetahui string tertentu.

Saya memiliki Database bernama A dengan sekitar 35 tabel, saya perlu mencari string bernama "halo" dan saya tidak tahu pada tabel mana string ini disimpan. Apakah mungkin?

Menggunakan MySQL

Saya seorang admin linux dan saya tidak terbiasa dengan database, akan sangat membantu jika Anda dapat menjelaskan kueri juga.

Kevin Parker
sumber
1
Lihat di sini: stackoverflow.com/a/5350405/330315
a_horse_with_no_name

Jawaban:

7

Kembali pada bulan Juli 2012 saya menulis posting ini

Permintaan untuk menemukan dan mengganti teks di semua tabel dan bidang mysql db

Ini menggunakan tabel information_schema.columns untuk mengambil setiap bidang CHAR, VARCHAR, dan TEXT dan melakukan PENGGANTIAN tekstual .

Silakan lihat tautan lama saya dan gunakan paradigma untuk melakukan pencarian.

Sebagai contoh, ini akan membuat SELECT terpisah untuk setiap kolom teks di setiap tabel

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;

Buat file teks SQL Giant dengan itu. Kemudian, jalankan skrip SQL Giant itu:

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

Output memberi tahu Anda Database, Tabel, dan Kolom tempat data muncul.

Cobalah !!!.

EDIT:

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

HARUS: tambahkan dua kutu kembali yang ditunjukkan di bawah ini untuk tabel yang memiliki spasi dalam namanya.

db,'.`',tb,'`',' WHERE
RolandoMySQLDBA
sumber
Solusi ini bekerja dengan sangat baik! Apakah perlu menyalin secara manual kueri awal ke baris variabel lingkungan demi baris? Saya dapat menyisipkan dan menjalankan kueri di dalam sesi mysql, tetapi tentunya mungkin juga untuk menyisipkan kueri itu ke dalam file?
John T
@ John II lakukan baris demi baris untuk menghindari keharusan menggulir jawaban saya secara vertikal. Anda dapat melakukan cara mana saja yang paling sederhana.
RolandoMySQLDBA
2

Mengambil pendekatan lain yang tidak memerlukan membangun query SQL, saya mengembangkan CRGREP sebagai alat baris perintah opensource gratis yang akan menangkap basis data (termasuk MySQL) dan mendukung jenis pencarian "fred customer.name" sederhana yang mencari "fred" di nama "" "kolom dari tabel" pelanggan "ke pencocokan pola yang lebih kompleks seperti" fr? d * .author "untuk pencocokan pola dengan semua kolom" penulis "di semua tabel.

Craig
sumber
2

Anda dapat mengembalikan semua kolom dari semua tabel yang cocok dengan nilai apa pun yang Anda cari sekaligus dengan membangun dari jawaban RolandoMySQLDBA dan menggunakan PREPAREdan EXECUTEmenjalankan kueri .

-- 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;
0b10011
sumber
1

Jika Anda dapat menggunakan bash - ini adalah skrip: Dibutuhkan pengguna dbread dengan pass dbread pada database.

#!/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

Jika ada yang menginginkan penjelasan: http://infofreund.de/?p=1670

chris2k
sumber
1

Jika Anda admin Linux, Anda harus terbiasa dengan baris perintah, jadi yang ini berguna:

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

Ubah root/ rootke kredensial mysql Anda (atau gunakan ~/.my.cnf), db_nameke nama database Anda dan foountuk teks pencarian Anda. Parameter --skip-extended-insertuntuk mysqldumpakan menampilkan setiap permintaan dalam baris terpisah. Parameter --color=autountuk grepakan menyoroti string Anda dan -wakan cocok dengan seluruh kata.

kenorb
sumber
0

Apakah Anda memiliki akses ke phpMyAdmin? Ini memiliki fitur pencarian untuk setiap basis data.

atau gunakan skrip pilihan Anda pada hasil (ubah 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 );
David
sumber
0

Saya fokus pada solusi template sederhana untuk pertanyaan Anda diimplementasikan dalam plsql untuk database Oracle , saya berharap menyesuaikannya di MySql, menjadi melempar googleing sederhana. yang Anda butuhkan hanyalah menyelidiki skema informasi di MySql dan mengganti beberapa nama tabel dan kolom.

Dalam skrip: ALL_TAB_COLUMNSadalah tabel skema informasi yang berisi Semua Kolom Tabel 'VARCHAR2', 'NVARCHAR2', 'NCHAR', 'CHAR' mengacu pada tipe kolom string di Oracle, Anda harus menggantinya dengan nama jenis equvalents dari MySql
% hello% adalah kata kunci pencarian ganti dengan string apa pun.

Hasilnya akan menjadi beberapa atau banyak skrip sql (berdasarkan pada jenis kolom tabel Anda) dan menjalankannya akan menghasilkan jawaban Anda
Juga kinerja dan konsumsi waktu akan menjadi masalah lain.
semoga ini bermanfaat

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')
Mohsen Heydari
sumber
0

Ada perpustakaan yang bagus untuk membaca semua tabel, 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...

}
mirhossein
sumber
0

Gunakan Trik Ini dengan Satu Baris Kode

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

column_name: Ketikkan semua nama kolom yang Anda cari.

table_name: Ketikkan semua nama Tabel di mana Anda mencari.

Sahil Jangra
sumber
Ini mungkin praktis dalam database yang sangat kecil - ini kurang begitu jika Anda mencoba menemukan nilai di ratusan tabel dan ribuan kolom. Berdasarkan kata-kata "seluruh database" dalam pertanyaan asli, saya berasumsi ini harus berurusan dengan semua tabel di DB.
RDFozz
0

Jika Anda menggunakan MySQL Workbench, klik kanan pada skema database dan pilih "Cari Tabel Data ..." kemudian isi formulir. Ini akan mencari seluruh basis data. Ketika (atau jika) hasilnya muncul, klik panah untuk memperluas. Ini akan menampilkan skema, tabel, data kunci utama, nama kolom dan data aktual yang cocok dengan pencarian Anda.
Kiat: Jika tidak ada yang muncul, coba perluas pencarian Anda.
Harap perhatikan bahwa ini hanya sangat berguna untuk mencari tipe data teks ( char, varchardan text).

kurdtpage
sumber