Ir para conteúdo

Arquivado

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

shini

[Resolvido] PDO consulta com IN

Recommended Posts

Estou fazendo uma consulta com o pdo usando o operador... so q n funciona... a consulta n fica formatada de forma correta....

 

$cgc é um array de checkbox q vem no seguinte formato:

 

[0]=>unidade1
[1]=>unidade2
[2]=>unidade3
[3]=>unidade4

 

 

public function findUnidadeVinculada($cgc){
  $sql = "SELECT c.numero_contrato, c.excluido, uc.unidade FROM contrato_unidade as uc
          INNER JOIN contratos AS c ON uc.contrato = c.id_contrato
          WHERE c.excluido = 'NAO' AND uc.unidade in (select cgc from unidades where cgc in(:cgc)) 
          LIMIT 1";

  $stmt = $this->con->prepare($sql);
  $stmt->execute(($cgc));

  $result = $stmt->fetch(PDO::FETCH_ASSOC);
  return $result;

}

 

se puderam ajudar fico grato.

 

-----------------------------

seria so trocar o ':cgc' por '?'

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiro, eEsse fragmento, dentro da sua query:

 

in(:cgc))

Caracteriza que você está usando named placeholders e, sendo assim, aquilo que você informa à PDOStatement::execute() deve ser um array associativo onde os índices refletem os apelidos utilizados sem os dois pontos:

 

$stmt -> execute(

   array( 'cgc' => $cgc )
);

Segundo. $cgc é um array mas até onde eu sei MySQL IN() espera receber uma string e, normalmente, separada por vírgulas. Mesmo que tal parâmetro seja aceito por PDOStatement::execute(), quando transitando para o banco, apenas o valor Array irá, pois é isso que acontece quando um Array normal é convertido forçadamente para string.

 

Terceiro. Você viu algum erro? "Não funciona" é muito vago, faça a PDO gritar alguns erros para saber o que está doendo nela. :P

Compartilhar este post


Link para o post
Compartilhar em outros sites

a consulta n retorna valor. estou usando o postgres. depois q mudei o :cgc para ?, apareceu o seguinte erro:

no match bound... [HY9300] algo assim...

Compartilhar este post


Link para o post
Compartilhar em outros sites

"no match bound" indica que os placeholders (named ou não) não batem com a quantidade de valores que está sendo atribuído ao statement.

 

Você está passando o array $cgc direto?

 

Você poderia tratá-lo, como uma string normal, utilizando implode para juntar com ',' (vírgulas), no final das contas PDO ainda trata a SQL como um string normal.

 

$stmt->execute(implode(',' , $cgc));
O que isso acima não é correto, pois não vai tratar parâmetro por parâmetro '-'

 

leia isso, do manual:

Citar
You cannot bind multiple values to a single parameter; for example, you cannot bind two values to a single named parameter in an IN() clause.

 

Você deve definir um placeholder para cada valor no IN.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Gabriel Heming, daqui a pouco testo o implode q você passou.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu tive de alterar a minha resposta antes. Mas isso foi antes de você responder. Repetindo, não seri nada aconselhável utilizar implode.

 

Conte o número de parâmetros utilizados no IN, e coloque a quantidade de marked placeholders ("?").

Compartilhar este post


Link para o post
Compartilhar em outros sites

pode passar de 200.... é variavel pode ser 5, 10, 300, 400....

Compartilhar este post


Link para o post
Compartilhar em outros sites

Infelizmente, "é a vida".

 

Você pode usar a função array_fill para "preencher" os marked placeholders.

 

Segue:

$quantidade = count($cgc);
$markedPlaceholders = array_fill(0 , $quantidade , '?');
$markedPlaceholders = implode(',' , $markedPlaceholders);

 

Com esse pequeno código acima, você possuirá a quantidade adequada de marked placeholders. Basta inserir no SQL.

$statement = $pdo->prepare('SELCT * FROM tabela WHERE id IN ('.$markedPlaceholders.');');

Compartilhar este post


Link para o post
Compartilhar em outros sites

shini...

 

Apenas curiosidade, esse SELECT faz sentido pra você?

select cgc from unidades where cgc in(:cgc)

 

Tipo... Selecione a coluna CGC em unidades que tenham CGC com essa lista de CGC.

A pergunta é igual a resposta, não?

Compartilhar este post


Link para o post
Compartilhar em outros sites

AND uc.unidade in (select cgc from unidades where cgc in(:cgc))

 

no caso uc.unidade seria td as unidades na tabela uc.. e cgc in(:cgc) seria somente os checkbox marcado pelo usuario.

 

 

seria assim uma unidade so pode estar vinculada a um contrato, dai fiz essa consulta para executa antes de inserir.

Compartilhar este post


Link para o post
Compartilhar em outros sites

AND uc.unidade in (select cgc from unidades where cgc in(:cgc))

 

no caso uc.unidade seria td as unidades na tabela uc.. e cgc in(:cgc) seria somente os checkbox marcado pelo usuario.

 

 

seria assim uma unidade so pode estar vinculada a um contrato, dai fiz essa consulta para executa antes de inserir.

 

 

Em alguns SGDB's, você pode informar os valores quotados

 

$stmt->execute('"' . implode('", "', $cgc) . '"');

Compartilhar este post


Link para o post
Compartilhar em outros sites
O que isso acima não é correto, pois não vai tratar parâmetro por parâmetro '-'

Mas que é contornável, isso é:

 

$cgc = array_map(

   array( $this -> conn, 'quote' ),

   $cgc
);

$cgc = implode( ', ', $cgc );

Agora, $cgc é uma string vinda de um array já tratado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas ainda assim depende do SGBD.

 

Veja que, segundo o manual, o método execute trata os parâmetros passados como PDO::PARAM_STR.

An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as PDO::PARAM_STR.

 

Sendo assim, digamos que possuimos os valores 1, 5 e 10.

 

A sql normal seria:

'SELECT * FROM tabela WHERE id IN (1 , 5 , 10);'

 

Entretanto, como passa-se o valor 1 , 5 , 10 em um único marked placeholder tratado como string. Dependendo do SGBD, por não ser apenas números passados, a SQL pode ser gerada da seguinte maneira:

"SELECT * FROM tabela WHERE id IN ('1 , 5 , 10');"

Utilizando quotes no único valor passado.

 

Não possuo certeza absoluta sobre isso. Mas conhecendo o comportamento dos SGBDs, isso é algo que eu esperaria acontecer.

 

Sei que o Postgre não quota dessa maneira, nem o MSServer. Mas já o mysql é outra história.

Compartilhar este post


Link para o post
Compartilhar em outros sites

são inteiros os parametros passados para o in

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tem como você dar um var_dump ou reconstruir a query manualmente para vermos como fica a consulta final?

 

Quanto a função in()

 

Creio que uso dela é assim:

in('string1', 'string2', 'string3');

 

ou

 

in(1,2,3); // com int

Compartilhar este post


Link para o post
Compartilhar em outros sites

mangakah, quando postei a duvida imaginei q passado uma array para o excute(); ele converteria o array em uma string separando os valores por virgula. n esperava ter q passar uma ? para cada valor no IN(), pq nesse caso pode variar podem ser 5 valores, 10, 200, 300

Compartilhar este post


Link para o post
Compartilhar em outros sites

são inteiros os parametros passados para o in

 

Nunca!!!!

 

 

Pode passar envolvido em aspas que o MySQL se encarrega da conversão.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Nunca!!!!

 

 

Pode passar envolvido em aspas que o MySQL se encarrega da conversão.

rsrs no meu caso são inteiros.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Gabriel Heming, testei hj seu codigo funcinou, mtooooo obrigado a todos q ajudaram.

 

[Resolvido]

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.