Cómo buscar en toda la base de datos MySQL una cadena particular

19

¿Es posible buscar tablas de una base de datos completa (fila y columna) para encontrar una cadena particular.

Tengo una base de datos llamada A con aproximadamente 35 tablas, necesito buscar la cadena llamada "hola" y no sé en qué tabla se guarda esta cadena. ¿Es posible?

Usando MySQL

Soy un administrador de Linux y no estoy familiarizado con las bases de datos, sería realmente útil si puedes explicar la consulta también.

Kevin Parker
fuente
1
Ver aquí: stackoverflow.com/a/5350405/330315
a_horse_with_no_name

Respuestas:

7

En julio de 2012 escribí esta publicación

Consulta para buscar y reemplazar texto en todas las tablas y campos de una base de datos mysql

Utiliza la tabla information_schema.columns para seleccionar todos los campos CHAR, VARCHAR y TEXT y realizar un REEMPLAZO textual .

Revise mi enlace anterior y use su paradigma para hacer una búsqueda.

Como ejemplo, esto creará un SELECT separado para cada columna de texto en cada tabla

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;

Cree un archivo de texto SQL gigante con él. Luego, ejecute ese script SQL gigante:

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

La salida le indica la base de datos, la tabla y la columna en la que aparecen los datos.

Darle una oportunidad !!!.

EDITAR:

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

DEBE: agregar los dos ticks posteriores que se muestran a continuación para las tablas que tienen un espacio en el nombre.

db,'.`',tb,'`',' WHERE
RolandoMySQLDBA
fuente
¡Esta solución funcionó muy bien! ¿Es necesario copiar manualmente la consulta inicial en una variable de entorno línea por línea? Pude pegar y ejecutar la consulta dentro de una sesión mysql, pero seguramente también es posible pegar esa consulta en un archivo.
John T
@JohnT II hago línea por línea para evitar tener que desplazar verticalmente mi respuesta. Puedes hacer lo que sea más simple.
RolandoMySQLDBA
2

Tomando otro enfoque que no requiere la creación de consultas SQL, desarrollé CRGREP como una herramienta gratuita de línea de comandos de código abierto que codificará las bases de datos (incluido MySQL) y admite búsquedas simples de tipo "fred customer.name" para "fred" en el "nombre "columna de la tabla" cliente "para una coincidencia de patrones más compleja como" fr? d * .author "para la coincidencia de patrones con todas las columnas" autor "en todas las tablas.

Craig
fuente
2

Puede devolver todas las columnas de todas las tablas que coincidan con todos los valores que está buscando a la vez, basándose en la respuesta de RolandoMySQLDBA y utilizando PREPAREy EXECUTEpara ejecutar la consulta .

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

Si puede usar un bash, aquí hay un script: necesita un usuario dbread con pass dbread en la base de datos.

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

Si alguien quiere una explicación: http://infofreund.de/?p=1670

chris2k
fuente
1

Si es administrador de Linux, debe estar familiarizado con la línea de comandos, por lo que esta sería útil:

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

Cambie root/ roota sus credenciales de mysql (o uso ~/.my.cnf), db_namea su nombre de base de datos y fooa su texto de búsqueda. El parámetro --skip-extended-insertpara mysqldumpmostrará cada consulta en líneas separadas. El parámetro --color=autopara grepresaltará su cadena y -wcoincidirá con la palabra completa.

kenorb
fuente
0

¿Tienes acceso a phpMyAdmin? Tiene una función de búsqueda para cada base de datos.

o use la secuencia de comandos de su elección en el resultado de (cambiar 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
fuente
0

Me concentro en una solución de plantilla simple para su pregunta implementada en plsql para la base de datos Oracle , espero personalizarla en MySql, siendo simple lanzar googleing. todo lo que necesita es investigar el esquema de información en MySql y reemplazar algunos nombres de tabla y columnas.

En el script: ALL_TAB_COLUMNSes una tabla de esquema de información que contiene todas las columnas de tabla 'VARCHAR2', 'NVARCHAR2', 'NCHAR', 'CHAR' se refiere a los tipos de columna de cadena en Oracle, debe reemplazarlos con nombres de tipo equivalentes de MySql
% hello% es la palabra clave de búsqueda reemplazarlo con cualquier cadena.

El resultado serán algunos o muchos scripts sql (basados ​​en los tipos de columna de sus tablas) y ejecutarlos dará como resultado su respuesta.
También el rendimiento y el consumo de tiempo serán otros asuntos.
espero que esto sea útil

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

Hay una buena biblioteca para leer todas las tablas, 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
fuente
0

Use este truco con una línea de código

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

nombre_columna: escriba el nombre de todas las columnas en las que busca.

nombre_tabla: escriba todo el nombre de la tabla en la que busca.

Sahil Jangra
fuente
Esto puede ser práctico en bases de datos muy pequeñas; lo es menos si está tratando de ubicar un valor en cientos de tablas y miles de columnas. Basado en la redacción "base de datos completa" en la pregunta original, supongo que esto debería tratar con todas las tablas en la base de datos.
RDFozz
0

Si está utilizando MySQL Workbench, haga clic con el botón derecho en el esquema de la base de datos y seleccione "Buscar datos de tabla ..." y luego complete el formulario. Esto buscará en toda la base de datos. Cuando (o si) aparecen los resultados, haga clic en la flecha para expandir. Mostrará el esquema, la tabla, los datos de la clave principal, el nombre de la columna y los datos reales que coinciden con su búsqueda.
Consejo: Si no aparece nada, intente ampliar su búsqueda.
Tenga en cuenta que esto sólo es realmente útil para la búsqueda de texto ( char, varchary text) tipos de datos.

kurdtpage
fuente