Belirli bir dize için tüm MySQL veritabanını arama


19

Belirli bir dizeyi bulmak için tüm veritabanı tablolarını (satır ve sütun) aramak mümkündür.

Yaklaşık 35 tablo ile A adlı bir Veritabanı yaşıyorum, ben "merhaba" adlı dize aramak gerekir ve bu dize hangi tabloya kaydedildi bilmiyorum. Mümkün mü?

MySQL Kullanımı

Ben bir linux admin ve veritabanlarına aşina değilim, u da sorguyu açıklayabilir eğer gerçekten yararlı olacaktır.


Yanıtlar:



7

Temmuz 2012'de bu yazıyı yazdım

Mysql db'nin tüm tablo ve alanlarındaki metni bulma ve değiştirme sorgusu

Her CHAR, VARCHAR ve TEXT alanını almak ve metinsel bir DEĞİŞTİRME gerçekleştirmek için information_schema.columns tablosunu kullanır .

Lütfen eski bağlantımı gözden geçirin ve arama yapmak için paradigmasını kullanın.

Örnek olarak, bu, her tablodaki her metin sütunu için ayrı bir SELECT oluşturur

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;

Onunla dev bir SQL metin dosyası oluşturun. Ardından, bu Dev SQL komut dosyasını yürütün:

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

Çıktı size verilerin göründüğü Veritabanı, Tablo ve Sütunu bildirir.

Bir şans ver !!!.

DÜZENLE:

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

ÖNEMLİ: adında boşluk olan tablolar için aşağıda gösterilen iki arka keneyi ekleyin.

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

Bu çözüm çok iyi çalıştı! İlk sorguyu elle bir ortam değişkenine satır satır kopyalamak gerekli mi? Sorguyu bir mysql oturumu içinde yapıştırıp çalıştırabildim, ancak elbette bu sorguyu bir dosyaya yapıştırmak da mümkün mü?
John T

@JohnT II cevabımı dikey olarak kaydırmaktan kaçınmak için satır satır yapıyor. En basit olanı yapabilirsiniz.
RolandoMySQLDBA

2

SQL sorguları oluşturmayı gerektirmeyen başka bir yaklaşım alarak, CRGREP'i veritabanlarını (MySQL dahil) grep edecek ve hem basit "fred customer.name" türü aramalarda "fred" için arama yapan "açık" komut satırı aracı olarak geliştirdim. "müşteri" tablosunun sütununu, tüm tablolardaki tüm "yazar" sütunlarına karşı desen eşleşmesi için "fr? d * .author" gibi daha karmaşık desen eşleşmesine yönlendirir.


2

Sen off inşa ederek tek seferde tüm aradığınız tüm değerleri eşleşen tüm tablolardan tüm sütunları dönebilirsiniz RolandoMySQLDBA cevabı ve kullanma PREPAREve EXECUTEsorguyu çalıştırmak için .

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

Bir bash kullanabiliyorsanız - işte bir betik: Veritabanında pass dbread ile bir kullanıcı dbread gerekiyor.

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

Birisi açıklama isterse: http://infofreund.de/?p=1670


1

Linux yöneticisiyseniz, komut satırına aşina olmalısınız, bu yüzden bu kullanışlı olacaktır:

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

Mysql kimlik bilgilerinizi root/ rootolarak değiştirin (veya kullanın ~/.my.cnf), db_nameveritabanı adınızı ve fooarama metninizi değiştirin. Parametre --skip-extended-insertiçin mysqldumpayrı çizgiler, her bir sorgu gösterecektir. Parametre --color=autoiçin grepsizin dize vurgular ve -wkelimenin tamamını eşleşir.


0

PhpMyAdmin'e erişiminiz var mı? Her veritabanı için bir arama özelliği vardır.

ya da (dbname adını değiştir) sonucunda seçtiğiniz komut dosyasını kullanın:

$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

Ben Oracle veritabanı için plsql uygulanan soru için basit bir şablon çözüm odaklanmak , ben basit atma googleing olmak, MySql üzerinde özelleştirme umuyoruz. tek ihtiyacınız olan MySql'deki bilgi şemasını araştırmak ve bazı tablo adı ve sütunlarını değiştirmek.

Komut dosyasında: ALL_TAB_COLUMNSTüm Tablo Sütunları 'VARCHAR2', 'NVARCHAR2', 'NCHAR', 'CHAR' içeren bir bilgi şeması tablosu , Oracle'daki dize sütun türlerini ifade eder, bunları MySql
% hello% eşdeğer tür adlarıyla değiştirmeniz gerekir arama anahtar sözcüğü herhangi bir dize ile değiştirin.

Sonuç, bazı veya çok sayıda sql komut dosyası (tablo sütun türlerinize bağlı olarak) olacak ve bunları çalıştırmak cevabınızla sonuçlanacaktır.
Ayrıca performans ve zaman tüketimi de başka konular olacaktır.
umarım bu faydalı olur

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

Tüm tabloları okumak için güzel bir kütüphane var, 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

Bu Hile Bir Satır Kod ile Kullan

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

column_name: Aradığınız tüm sütunların adını yazın.

table_name: Aradığınız tüm Tablo adını yazın.


Bu, çok küçük veritabanlarında pratik olabilir - bu yüzden yüzlerce tablo ve binlerce sütun arasında bir değer bulmaya çalışıyorsanız daha azdır. Orijinal soruda "bütün veritabanı" ifadesine dayanarak, bu DB tüm tabloları ile ilgilenmesi gerektiğini varsayıyorum.
RDFozz

0

MySQL Workbench kullanıyorsanız, veritabanı şemasına sağ tıklayın ve "Tablo Verilerini Ara ..." seçeneğini seçin ve formu doldurun. Bu, tüm veritabanını arayacaktır. Sonuçlar ortaya çıktığında (ya da eğer), genişletmek için oka tıklayın. Şema, tablo, birincil anahtar verileri, sütun adı ve aramanızla eşleşen gerçek verileri gösterir.
İpucu: Hiçbir şey gelmezse, aramanızı genişletmeyi deneyin.
Bu yalnızca metin arama için gerçekten yararlıdır (lütfen unutmayın char, varcharve textveri tipleri).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.