Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

paulojuchem

[Resolvido] Utilizando LIKE para colunas nao conhecidas

Recommended Posts

Olá,

Suponha que voce tenha uma view X com N campos, voce sabe o nome da view, mas nao sabe o nome de nenhum campo da mesma e voce precisa pegar somente os dados que sejam LIKE '%alguma_coisa%' de qualquer um dos campos desta view.

É possivel?

Ex.:

SELECT * FROM "nome_da_view" WHERE * LIKE '%alguma_coisa%';

Tem como colocar alguma coisa no lugar do segundo asterisco? =P

Pode parecer algo idiota, mas isso me obriga a criar um arquivo com a query correta para cada consulta que eu tenho que fazer, entao, qualquer ajuda é bem vindo....

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Com base na tabela de metadados a query poderia ser montada dinamicamente para cada coluna do tipo char.

Só não sei se a tabela de colunas tem as colunas de uma view (no Oracle por exemplo tem).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não sei, só testando Andrey.

 

A ideia seria, supondo uma tabela assim

 

tabela
------
campo1 char
campo2 integer
campo3 char
campo4 date
campo5 char

 

Um select lê a tabela de metadados

 

SELECT COLUMN_NAME
 FROM INFORMATION_SCHEMA.COLUMNS
 WHERE table_name = 'tabela'
 AND COLUMN_TYPE = 'char'

 

teria este result

 

campo1

campo3

campo5

 

o select montado seria

 

select *
from tabela
where
(
campo1 like '%motta%'
or
campo3 like '%motta%'
or
campo5 like '%motta%'
)

 

a parte

campoX like ...

seria um loop do cursor, claro.

 

 

uma ideia básica, se uma coluna6 fosse criada na próxima execução ela seria tratada automaticamente.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou tentando entender essa parte de SQL dinamica...

Eu poderia fazer uma query somente para pegar os indices e usa-los na comparacao, mas nao me parece algo inteligente...

 

Outra coisa que eu havia pensado era +- nisso

 

SELECT p.* FROM view p WHERE 'alguma_coisa' IN(SELECT * FROM view s WHERE s.id=p.id)

 

O problema e que o select de dentro retorna mais de 1 coluna... tentei concatenar para virar uma string mas n foi....

Compartilhar este post


Link para o post
Compartilhar em outros sites

Deixa eu dar a última tacada .. por favor.

DELIMITER $$
CREATE PROCEDURE `findAll` ( IN `tableName` VARCHAR( 28 ) , IN `search` TEXT ) 
LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL
BEGIN
      DECLARE finished INT DEFAULT FALSE ;
      DECLARE columnName VARCHAR ( 28 ) ;
      DECLARE stmtFields TEXT ;
      DECLARE columnNames CURSOR FOR 
             SELECT DISTINCT `COLUMN_NAME` FROM `information_schema`.`COLUMNS`
             WHERE `TABLE_NAME` = tableName ORDER BY `ORDINAL_POSITION` ;
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = TRUE;
      SET stmtFields = '' ;
      OPEN columnNames ;
      readColumns: LOOP
             FETCH columnNames INTO columnName ;
             IF finished THEN 
                    LEAVE readColumns ;
             END IF;
             SET stmtFields = CONCAT( 
                    stmtFields , IF ( LENGTH( stmtFields ) > 0 , ' AND' , ''  ) , 
                    ' `', tableName ,'`.`' , columnName , '` LIKE "' , search , '"' 
             ) ; 
      END LOOP;
      SET @stmtQuery := CONCAT ( 'SELECT * FROM `' , tableName , '` WHERE ' , stmtFields ) ;
      PREPARE stmt FROM @stmtQuery ;
      EXECUTE stmt ;
      CLOSE columnNames ;
END ;
$$
DELIMITER ;

 

:seta:

 

CALL findAll ( 'messages' , '%termo a ser pequisado%' ) ;

 

:seta:

 

SELECT * FROM `messages` WHERE `messages`.`mid` LIKE "%termo a ser pequisado%" AND `messages`.`uid` LIKE "%
termo a ser pequisado%" AND `messages`.`text` LIKE "%termo a ser pequisado%" AND `messages`.`date` LIKE "%term
o a ser pequisado%"

 

E só pra lembrar, eu não declarei todos os handlers para os erros possíveis não, portanto você vai ter que fazer isso por conta própria.

Compartilhar este post


Link para o post
Compartilhar em outros sites

cara, que massa andrei , so uma duvida, eu nao criei procedimentos ainda, o simples fato de eu executar o codigo do procedimento, apos isso, poderei chamar ele simplismente por CALL nome_do_procedimento(param1,paramN..) ?

 

andrey, quando eu nao passo nenhum valor no parametro search, a query esta retornando todos os valores, o que esta correto, porem, quando eu insiro algo, nada e encontrado...

Obs.: Ainda estou tentando entender o procedimento, caso tenha algo a acrescentar, eu agradeco. Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ola, encontrei uma solucao, infelizmente sao necessarias 3 queryes , uma para pegar as colunas, outra para contar o total de registros p/ paginar os resultados e a ultima p/ pegar os resultados... segue um exemplo

//aqui eu pego quais sao as colunas que tem na tabela

//o valor que retorna e armazenado em uma var no php, que monta todos os likes p/ todas as colunas

SHOW COLUMNS FROM 'nome_da_tabela'

//aqui eu vejo o total de resultados da query e uso p/ paginar depois...

SELECT COUNT(*) AS rows FROM 'nome_da_tabela' + "tratamento_da_string_da_query_das_colunas_para_likes ";

//aqu ieu pego os valores e monto a array data

SELECT * FROM 'nome_da_tabela' + "tratamento_da_string_da_query_das_colunas_para_likes ";

 

Conclusao: Funciona, mas olha a gambi hehehe, assim que eu entender o que o andrey postou irei postar minhas consideracoes, ainda so meio amador haha...

Abracos

Compartilhar este post


Link para o post
Compartilhar em outros sites

cara, que massa andrei , so uma duvida, eu nao criei procedimentos ainda, o simples fato de eu executar o codigo do procedimento, apos isso, poderei chamar ele simplismente por CALL nome_do_procedimento(param1,paramN..) ?

 

andrey, quando eu nao passo nenhum valor no parametro search, a query esta retornando todos os valores, o que esta correto, porem, quando eu insiro algo, nada e encontrado...

Obs.: Ainda estou tentando entender o procedimento, caso tenha algo a acrescentar, eu agradeco. Obrigado.

 

Você chama 'CALL findAll ( nomeDaTabela , valorParaTodosOsLikes ) ;'

Compartilhar este post


Link para o post
Compartilhar em outros sites

Andrey, a procedure que voce postou funcionou, abaixo as alteracoes feitas:

... stmtFields , IF ( LENGTH( stmtFields ) > 0 , ' AND' , '' ) , ... ficou

....stmtFields , IF ( LENGTH( stmtFields ) > 0 , ' OR' , '' ) , ...

AND trocado por OR, ja que quaisquer um dos campos compativeis ja sao suficientes.

 

e

 

...CONCAT ( 'SELECT * FROM `' , tableName , '` WHERE ' , stmtField... ficou

...CONCAT ( 'SELECT * FROM `' , tableName , '` WHERE' , stmtField...

O espaco apos o where era preenchido com o espaco antes do LIKE, assim, ficavam 2 espacos.

 

ficou fantastico :D

 

Duvida:

... SELECT DISTINCT `COLUMN_NAME` FROM `information_schema`.`COLUMNS` ...

O select acima seleciona todas as colunas da tabela, inclusive as ja excluidas, eu tinha um campo antigamente na tabela, chamado Y, este campo foi excluido, mas o where ainda tenta dar um LIKE Y hehe, quando eu trabalho com views nao tenho esse problema, mas eu estava tentando padronizar tanto para tabelas normais quanto para views.

 

Duvida2: Posso passar um terceiro parametro p/ a procedure com o limit?

Abracos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Andrey, a procedure que voce postou funcionou, abaixo as alteracoes feitas:

... stmtFields , IF ( LENGTH( stmtFields ) > 0 , ' AND' , '' ) , ... ficou

....stmtFields , IF ( LENGTH( stmtFields ) > 0 , ' OR' , '' ) , ...

AND trocado por OR, ja que quaisquer um dos campos compativeis ja sao suficientes.

Isso era a seu critério !

 

...CONCAT ( 'SELECT * FROM `' , tableName , '` WHERE ' , stmtField... ficou

...CONCAT ( 'SELECT * FROM `' , tableName , '` WHERE' , stmtField...

O espaco apos o where era preenchido com o espaco antes do LIKE, assim, ficavam 2 espacos.

Havia percebido, mas não faz muita diferença, no final das contas a query não é exibida pra você e isso não atrapalha na execução .. eu tenho costume de dar um monte de espaço para o código ficar bem legível.

 

 

Duvida:

... SELECT DISTINCT `COLUMN_NAME` FROM `information_schema`.`COLUMNS` ...

O select acima seleciona todas as colunas da tabela, inclusive as ja excluidas, eu tinha um campo antigamente na tabela, chamado Y, este campo foi excluido, mas o where ainda tenta dar um LIKE Y hehe, quando eu trabalho com views nao tenho esse problema, mas eu estava tentando padronizar tanto para tabelas normais quanto para views.

Isso é estranho, o distinct nesse caso serve apenas para eliminar a repetição.

 

Duvida2: Posso passar um terceiro parametro p/ a procedure com o limit?

 

:seta:

 

`findAll`(IN `tableName` VARCHAR( 28 ) , IN `search` TEXT , IN `Param3` VARCHAR, IN `Param4` VARCHAR)

 

[iN,OUT,INOUT] => Contexto

IN => Parâmetros de entrada,
OUT => Parâmetros de saída,
INOUT => Contexto para ambos os lados 

 

`[...]` Nome do parâmetro , o varchar alí você já deve saber do que se trata ..

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ola prog!

As vezes sao somente 2 colunas, varia de acordo com a tabela que eu passo para a funcao, as vezes ate mesmo FKS, porem, quando eu crio as views, as FKS sao transoformadas nas respectivas strings da FK.

 

Andrey, consegui adicionar limit com sucesso!

 

Duvida:

...

OUT => Parâmetros de saída,

...

Esse parametro de saida, eu consigo retornar, por exemplo, uma array na seguinte estrutura:

array(

'dados '=> retorno_da_query,

'totalDePaginas' => alguma_var_que_vai_pegar_count_dentro_da_procedure

)

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.