Como pesquisar no banco de dados MySQL inteiro por uma string específica


19

é possível pesquisar uma tabela inteira do banco de dados (linha e coluna) para descobrir uma sequência específica.

Estou tendo um banco de dados chamado A com cerca de 35 tabelas, preciso pesquisar a sequência chamada "hello" e não sei em qual tabela essa sequência é salva. É possível?

Usando o MySQL

Eu sou um administrador Linux e não estou familiarizado com bancos de dados, seria realmente útil se você puder explicar a consulta também.


Respostas:



7

Em julho de 2012, escrevi este post

Consulta para encontrar e substituir texto em todas as tabelas e campos de um banco de dados mysql

Ele usa a tabela information_schema.columns para selecionar todos os campos CHAR, VARCHAR e TEXT e executar um texto REPLACE .

Por favor, dê uma olhada no meu link antigo e use seu paradigma para fazer uma pesquisa.

Como exemplo, isso criará um SELECT separado para cada coluna de texto em cada tabela

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;

Crie um arquivo de texto SQL gigante com ele. Em seguida, execute esse 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

A saída informa o banco de dados, a tabela e a coluna em que os dados aparecem.

De uma chance !!!.

EDITAR:

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

DEVE: adicionar os dois ticks mostrados abaixo para tabelas que possuem um espaço no nome.

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

Esta solução funcionou muito bem! É necessário copiar manualmente a consulta inicial em uma variável de ambiente linha por linha? Consegui colar e executar a consulta dentro de uma sessão mysql, mas certamente é possível também colar essa consulta em um arquivo?
John T

O @JohnT II faz linha por linha para evitar ter que rolar verticalmente minha resposta. Você pode fazer o que for mais simples.
RolandoMySQLDBA 22/02

2

Adotando outra abordagem que não requer a criação de consultas SQL, desenvolvi o CRGREP como uma ferramenta de linha de comando gratuita de código- fonte aberto que grep bancos de dados (incluindo MySQL) e suporta tanto o tipo simples "fred customer.name" procura por "fred" no "nome "coluna da tabela" customer "para uma correspondência mais complexa de padrões, como" fr? d * .author ", para correspondência de padrões em todas as colunas" autor "em todas as tabelas.


2

Você pode retornar todas as colunas de todas as tabelas que correspondam aos valores que você está procurando ao mesmo tempo, baseando-se na resposta do RolandoMySQLDBA e usando PREPAREe EXECUTEexecutando a 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;

1

Se você pode usar um bash - aqui está um script: Ele precisa de um usuário dbread com pass dbread no banco de dados.

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

Se alguém quiser uma explicação: http://infofreund.de/?p=1670


1

Se você é administrador do Linux, deve estar familiarizado com a linha de comando, portanto, este seria útil:

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

Mude root/ rootpara suas credenciais mysql (ou use ~/.my.cnf), db_namepara o nome do seu banco de dados e foopara o seu texto pesquisado. O parâmetro --skip-extended-insertfor mysqldumpexibirá cada consulta em linhas separadas. O parâmetro --color=autofor grepdestacará sua string e -wcorresponderá à palavra inteira.


0

Você tem acesso ao phpMyAdmin? Possui um recurso de pesquisa para cada banco de dados.

ou use o script de sua escolha no resultado de (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 );

0

Eu me concentro em uma solução de modelo simples para sua pergunta implementada em plsql para banco de dados Oracle , espero personalizá-la no MySql, sendo simples jogar googleing. tudo o que você precisa é investigar o esquema de informações no MySql e substituir algum nome de tabela e colunas.

No script: ALL_TAB_COLUMNSé uma tabela de esquema de informações que contém todas as colunas da tabela 'VARCHAR2', 'NVARCHAR2', 'NCHAR', 'CHAR' refere-se aos tipos de coluna de string no Oracle, você deve substituí-los por nomes de tipo equivalentes do MySql
% hello% é a palavra-chave de pesquisa, substitua-a por qualquer sequência.

O resultado serão alguns ou muitos scripts sql (com base nos tipos de coluna das tabelas) e a execução deles resultará em sua resposta
Também o desempenho e o consumo de tempo serão outros assuntos.
espero que isso seja ú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')

0

Existe uma boa biblioteca para ler todas as tabelas, 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

Use este truque com uma linha de código

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

nome_da_coluna: digite o nome de todas as colunas em que você pesquisar.

nome_tabela: digite todo o nome da tabela em que você procura.


Isso pode ser prático em bancos de dados muito pequenos - é menos se você estiver tentando localizar um valor em centenas de tabelas e milhares de colunas. Com base no texto "banco de dados inteiro" na pergunta original, suponho que isso deva lidar com todas as tabelas no banco de dados.
RDFozz

0

Se você estiver usando o MySQL Workbench, clique com o botão direito do mouse no esquema do banco de dados e selecione "Pesquisar dados da tabela ..." e preencha o formulário. Isso pesquisará todo o banco de dados. Quando (ou se) os resultados aparecerem, clique na seta para expandir. Ele mostrará o esquema, a tabela, os dados da chave primária, o nome da coluna e os dados reais que correspondem à sua pesquisa.
Dica: Se nada aparecer, tente ampliar sua pesquisa.
Observe que isso é realmente útil apenas para pesquisar tipos de dados de texto ( char, varchare text).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.