So durchsuchen Sie die gesamte MySQL-Datenbank nach einer bestimmten Zeichenfolge

19

Ist es möglich, eine ganze Datenbanktabelle (Zeile und Spalte) zu durchsuchen, um eine bestimmte Zeichenfolge zu ermitteln?

Ich besitze eine Datenbank mit dem Namen A und ungefähr 35 Tabellen. Ich muss nach der Zeichenfolge mit dem Namen "Hallo" suchen und weiß nicht, auf welcher Tabelle diese Zeichenfolge gespeichert ist. Ist dies möglich?

Verwenden von MySQL

Ich bin ein Linux-Administrator und ich bin nicht vertraut mit Datenbanken, es wäre sehr hilfreich, wenn Sie die Abfrage auch erklären können.

Kevin Parker
quelle
1
Siehe hier: stackoverflow.com/a/5350405/330315
a_horse_with_no_name

Antworten:

7

Bereits im Juli 2012 habe ich diesen Beitrag geschrieben

Abfrage zum Suchen und Ersetzen von Text in allen Tabellen und Feldern einer MySQL-Datenbank

Es verwendet die Tabelle information_schema.columns , um jedes CHAR-, VARCHAR- und TEXT-Feld aufzunehmen und ein textuelles REPLACE durchzuführen .

Bitte schauen Sie sich meinen alten Link an und verwenden Sie sein Paradigma, um eine Suche durchzuführen.

So wird beispielsweise für jede Textspalte in jeder Tabelle ein separates SELECT erstellt

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;

Erstellen Sie damit eine Giant SQL-Textdatei. Führen Sie dann das folgende Giant SQL-Skript aus:

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

Die Ausgabe informiert Sie über die Datenbank, Tabelle und Spalte, in der die Daten angezeigt werden.

Versuche es !!!.

BEARBEITEN:

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

MÜSSEN: Fügen Sie die beiden folgenden hinteren Häkchen für Tabellen hinzu, deren Name ein Leerzeichen enthält.

db,'.`',tb,'`',' WHERE
RolandoMySQLDBA
quelle
Diese Lösung hat sehr gut funktioniert! Muss die ursprüngliche Abfrage zeilenweise manuell in eine Umgebungsvariable kopiert werden? Ich konnte die Abfrage in einer MySQL-Sitzung einfügen und ausführen, aber es ist sicherlich auch möglich, diese Abfrage in eine Datei einzufügen.
John T
@JohnT II zeilenweise ausführen, um zu vermeiden, dass meine Antwort vertikal gescrollt wird. Sie können den einfachsten Weg wählen.
RolandoMySQLDBA
2

Mit einem anderen Ansatz, bei dem keine SQL-Abfragen erstellt werden müssen, habe ich CRGREP als kostenloses OpenSource-Befehlszeilentool entwickelt, das Datenbanken (einschließlich MySQL) durchsucht und sowohl einfache "fred customer.name" -Typsuchen nach "fred" im "Namen" unterstützt "Spalte der Tabelle" customer "für komplexere Mustervergleiche wie" fr? d * .author "für den Mustervergleich mit allen" author "-Spalten in allen Tabellen.

Craig
quelle
2

Sie können alle Spalten aus allen Tabellen, die mit allen gesuchten Werten übereinstimmen, gleichzeitig zurückgeben, indem Sie die Antwort von RolandoMySQLDBA verwenden PREPAREund EXECUTEdie Abfrage mit und ausführen .

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

Wenn Sie eine Bash verwenden können - hier ist ein Skript: Es benötigt einen Benutzer dbread mit pass dbread für die Datenbank.

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

Wenn jemand eine Erklärung möchte: http://infofreund.de/?p=1670

chris2k
quelle
1

Wenn Sie Linux-Administrator sind, sollten Sie mit der Befehlszeile vertraut sein.

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

Ändern Sie root/ rootzu Ihren MySQL-Anmeldeinformationen (oder verwenden Sie diese ~/.my.cnf), db_namezu Ihrem Datenbanknamen und foozu Ihrem Suchtext. Parameter --skip-extended-insertfür mysqldumpzeigt jede Abfrage in separaten Zeilen an. Der Parameter --color=autofür grephebt Ihre Zeichenfolge hervor und -wstimmt mit dem gesamten Wort überein.

Kenorb
quelle
0

Hast du Zugriff auf phpMyAdmin? Es hat eine Suchfunktion für jede Datenbank.

Oder verwenden Sie ein Skript Ihrer Wahl für das Ergebnis von (change 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
quelle
0

Ich konzentriere mich auf eine einfache Vorlagenlösung für Ihre Frage, die in der plsql für Oracle- Datenbank implementiert ist. Ich hoffe, dass ich sie auf MySql anpassen kann, indem ich einfach google. Sie müssen lediglich das Informationsschema in MySQL untersuchen und einige Tabellennamen und Spalten ersetzen.

Im Skript: IstALL_TAB_COLUMNS eine Informationsschematabelle mit allen Tabellenspalten "VARCHAR2", "NVARCHAR2", "NCHAR", "CHAR" bezieht sich auf Zeichenfolgenspaltentypen in Oracle. Sie müssen sie durch gleichwertige Typnamen von MySql
% hello% ersetzen. Ist das Suchwort, ersetzen Sie es durch eine beliebige Zeichenfolge.

Das Ergebnis sind einige oder viele SQL-Skripte (basierend auf Ihren Tabellenspaltentypen), und die Ausführung dieser Skripte führt zu Ihrer Antwort.
Auch die Leistung und der Zeitaufwand sind von Bedeutung.
Ich hoffe, das wird nützlich sein

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

Es gibt eine schöne Bibliothek zum Lesen aller Tabellen, 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
quelle
0

Verwenden Sie diesen Trick mit einer Codezeile

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

Spaltenname: Geben Sie den Namen aller Spalten ein, in denen Sie suchen.

Tabellenname: Geben Sie den gesamten Tabellennamen ein, in dem Sie suchen.

Sahil Jangra
quelle
Dies kann in sehr kleinen Datenbanken praktisch sein - weniger, wenn Sie versuchen, einen Wert in Hunderten von Tabellen und Tausenden von Spalten zu finden. Basierend auf der Formulierung "gesamte Datenbank" in der ursprünglichen Frage gehe ich davon aus, dass dies für alle Tabellen in der DB gelten sollte.
RDFozz
0

Wenn Sie MySQL Workbench verwenden, klicken Sie mit der rechten Maustaste auf das Datenbankschema und wählen Sie "Tabellendaten durchsuchen ...". Füllen Sie dann das Formular aus. Dadurch wird die gesamte Datenbank durchsucht. Wenn (oder wenn) die Ergebnisse angezeigt werden, klicken Sie zum Erweitern auf den Pfeil. Es werden das Schema, die Tabelle, die Primärschlüsseldaten, der Spaltenname und die tatsächlichen Daten angezeigt, die Ihrer Suche entsprechen.
Tipp: Wenn sich nichts ergibt, erweitern Sie Ihre Suche.
Bitte beachten Sie, dass dies nur dann wirklich nützlich ist , Text für die Suche ( char, varcharund text) Datentypen.

kurdtpage
quelle