Jak przeszukać całą bazę danych MySQL pod kątem określonego ciągu

19

czy możliwe jest przeszukiwanie całych tabel bazy danych (wiersza i kolumny) w celu znalezienia określonego ciągu.

Mam bazę danych o nazwie A z około 35 tabelami, muszę wyszukać ciąg o nazwie „hello” i nie wiem, w której tabeli zapisano ten ciąg. Czy to możliwe?

Korzystanie z MySQL

Jestem administratorem Linuksa i nie znam baz danych, byłoby bardzo pomocne, gdybyś mógł wyjaśnić zapytanie.

Kevin Parker
źródło
1
Zobacz tutaj: stackoverflow.com/a/5350405/330315
a_horse_w_na_nazwie

Odpowiedzi:

7

W lipcu 2012 roku napisałem ten post

Zapytanie, aby znaleźć i zamienić tekst we wszystkich tabelach i polach bazy danych mysql

Wykorzystuje tabelę information_schema.columns do pobrania każdego pola CHAR, VARCHAR i TEXT i wykonania tekstowej zamiany .

Proszę przejrzeć mój stary link i użyć jego paradygmatu, aby przeprowadzić wyszukiwanie.

Na przykład spowoduje to utworzenie osobnego WYBORU dla każdej kolumny tekstowej w każdej tabeli

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;

Utwórz z nim plik tekstowy Giant SQL. Następnie uruchom skrypt 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

Dane wyjściowe informują o bazie danych, tabeli i kolumnie, w której pojawiają się dane.

Spróbuj !!!.

EDYTOWAĆ:

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

POWINIEN: dodać dwa tylne tiki pokazane poniżej dla tabel, które mają spacje w nazwie.

db,'.`',tb,'`',' WHERE
RolandoMySQLDBA
źródło
To rozwiązanie działało bardzo dobrze! Czy konieczne jest ręczne skopiowanie początkowego zapytania do zmiennej środowiskowej wiersz po wierszu? Byłem w stanie wkleić i uruchomić zapytanie w sesji mysql, ale z pewnością można również wkleić to zapytanie do pliku?
John T
@JohnT II wykonuj wiersz po wierszu, aby uniknąć konieczności przewijania mojej odpowiedzi w pionie. Możesz zrobić to, co jest najprostsze.
RolandoMySQLDBA
2

Stosując inne podejście, które nie wymaga budowania zapytań SQL, opracowałem CRGREP jako bezpłatne narzędzie wiersza poleceń open source, które będzie grepować bazy danych (w tym MySQL) i obsługuje zarówno proste „fred customer.name” wyszukuje „fred” w „name” „kolumna tabeli„ klienta ”do bardziej złożonego dopasowania wzorca, takiego jak„ fr? d * .author ”do dopasowania wzorca względem wszystkich kolumn„ autora ”we wszystkich tabelach.

Craig
źródło
2

Możesz zwrócić wszystkie kolumny ze wszystkich tabel, które pasują do wszystkich poszukiwanych wartości naraz, budując odpowiedź RolandoMySQLDBA oraz używając PREPAREi EXECUTEuruchamiając zapytanie .

-- 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
źródło
1

Jeśli możesz użyć bash - oto skrypt: Potrzebuje on dbread użytkownika z pass dbread w bazie danych.

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

Jeśli ktoś chce wyjaśnienia: http://infofreund.de/?p=1670

chris2k
źródło
1

Jeśli jesteś administratorem Linuksa, powinieneś znać wiersz poleceń, więc ten byłby przydatny:

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

Zmień root/ rootna dane uwierzytelniające mysql (lub użyj ~/.my.cnf), db_namena nazwę bazy danych i foona szukany tekst. Parametr --skip-extended-insertdla mysqldumpwyświetli każde zapytanie w osobnych wierszach. Parametr --color=autodla greppodświetli Twój ciąg i -wdopasuje całe słowo.

kenorb
źródło
0

Czy masz dostęp do phpMyAdmin? Posiada funkcję wyszukiwania dla każdej bazy danych.

lub użyj wybranego skryptu w wyniku (zmień nazwę_db):

$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
źródło
0

Skupiam się na prostym rozwiązaniu szablonowym dla twojego pytania zaimplementowanym w plsql dla bazy danych Oracle , mam nadzieję, że dostosuję go do MySql, będąc prostym rzutem googleing. wszystko czego potrzebujesz to zbadanie schematu informacji na MySql i zastąpienie niektórych nazw tabel i kolumn.

W skrypcie: ALL_TAB_COLUMNSjest tabelą schematów informacyjnych zawierającą wszystkie kolumny tabeli „VARCHAR2”, „NVARCHAR2”, „NCHAR”, „CHAR” odnosi się do typów kolumn łańcuchowych w Oracle, musisz je zastąpić nazwami typów ekwiwalentów MySql
% hello% to słowo kluczowe wyszukiwania zastąp je dowolnym ciągiem.

Rezultatem będzie kilka lub wiele skryptów SQL (opartych na typach kolumn w tabelach), a ich uruchomienie da odpowiedź.
Kolejną sprawą będzie wydajność i zużycie czasu.
mam nadzieję, że to się przyda

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
źródło
0

Jest fajna biblioteka do czytania wszystkich stolików, 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
źródło
0

Użyj tej sztuczki z jedną linią kodu

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

nazwa_kolumny: wpisz nazwę wszystkich kolumn, w których szukasz.

nazwa_tabeli: Wpisz całą nazwę tabeli, w której szukasz.

Sahil Jangra
źródło
Może to być praktyczne w bardzo małych bazach danych - jest to mniej ważne, jeśli próbujesz zlokalizować wartość w setkach tabel i tysięcy kolumn. Opierając się na sformułowaniu „cała baza danych” w pierwotnym pytaniu, zakładam, że powinno to dotyczyć wszystkich tabel w bazie danych.
RDFozz
0

Jeśli korzystasz z MySQL Workbench, kliknij prawym przyciskiem myszy schemat bazy danych i wybierz „Wyszukaj dane tabeli ...”, a następnie wypełnij formularz. Spowoduje to przeszukanie całej bazy danych. Kiedy (lub jeśli) pojawią się wyniki, kliknij strzałkę, aby rozwinąć. Wyświetli schemat, tabelę, dane klucza podstawowego, nazwę kolumny i rzeczywiste dane pasujące do wyszukiwania.
Wskazówka: jeśli nic się nie pojawi, spróbuj poszerzyć wyszukiwanie.
Należy pamiętać, że jest to tylko bardzo przydatne do wyszukiwania tekstu ( char, varchari text) typy danych.

kurdtpage
źródło