Pergunta

Eu estou brincando com declarações preparadas em PHP / DOP. O básico fina consultas de trabalho, passando um valor para a cláusula WHERE:

$stmt = $db->prepare( 'SELECT title FROM episode WHERE id=:id' );
$stmt->bindParam( ':id', $id, PDO::PARAM_INT );
$id = 5;
$stmt->execute();

No entanto Eu tenho uma situação onde eu preciso passar variáveis ??para os nomes de campo. Esta consulta (com ligação apropriada) funciona bem:

SELECT :field FROM episode WHERE id=:id

Este dá um erro:

SELECT title FROM :field WHERE id=:id

Este não dá um erro, mas não retorna nenhuma linha:

SELECT title FROM episode WHERE :field=:id

Então, o que as coisas devem funcionar em declarações preparadas? Posso 'parametrizar os nomes de campo, nomes de tabelas e assim por diante?

Foi útil?

Solução

Você não pode parametrizar nomes de tabela, nomes de coluna, ou qualquer coisa em uma cláusula IN (graças a c0r0ner para apontando a restrição cláusula IN).

Consulte esta questão , e posteriormente este comentário no PHP manual.

Outras dicas

@ Josh Leitzel

Esse pensamento é muito restritiva (e na minha opinião é apenas uma desculpa para estar com preguiça de implementar uma solução robusta), especialmente para estruturas de árvore dinâmicas expressas numa base de dados.

Considere o seguinte exemplo:

Meu projeto tem uma estrutura lógica:

A hierarquia da empresa é expresso em termos de entidades. Cada entidade pode tratados, no caso geral de ser um membro da hierarquia ou como um membro de um determinado nível de hierarquia. A hierarquia em si é definido em uma tabela como um único ramo de árvore da seguinte forma:

entity_structure (
   id
   name
   parent_entity_structure_id
);

e as entidades em si são expressas como:

entities (
   id
   name
   entity_structure_id
   parent_id
);

Para facilidade de uso Eu construí um algoritmo que cria uma vista plana da árvore. O exemplo concreto a seguir ilustra o que quero dizer:

SELECT * FROM entity_structure;

id      | name               | entity_structure_parent_id
-----------------------------------------------------------
1       | Company            | null    (special one that always exists)
2       | Division           | 1
3       | Area               | 2
4       | Store              | 3

Isto resultaria na representação plana seguinte a ser produzida:

entity_tree (
   entity_id
   division_id
   area_id
   store_id
)

As entidades que estão no nível de divisão teria division_id, area_id e STORE_ID como NULL, Uma área area_id e STORE_ID como NULL, etc.

A coisa agradável sobre este é que permite consultar todos os filhos de uma divisão usando uma instrução semelhante à seguinte:

SELECT * FROM entity_tree WHERE division_id = :division_id;

No entanto, isto pressupõe que eu sei que o nível da estrutura da entidade estou consultando. Seria bom fazer:

SELECT * FROM entity_tree WHERE :structure = :entity_id;

Eu sei que não é difícil descobrir o nível de estrutura de uma única entidade, mas supor que eu estou looping através de um conjunto de entidades que podem não estar todos no mesmo nível. Como é agora eu tenho que criar uma consulta separada para cada nível da hierarquia, mas se eu pudesse parametrizar campos que eu poderia fazer o seguinte:

$children = array();
$stmt = $pdo->prepare('SELECT entity_id FROM entity_tree WHERE :structure = :entityId');
foreach ($entities AS $entity) {
   $stmt->execute(array(
      ':structure' = $entity->getEntityStructureId(),
      ':entityId'  = $entity->getId()
   ));

   $children[$entity->getId()] = $stmt->fetchAll(PDO::FETCH_COLUMN);
}

resultando em um código mais limpo e apenas uma declaração preparada.

Todo o exemplo não usa qualquer entrada do usuário.

Apenas algo a considerar.

Você não pode parametrizar qualquer coisa dentro cláusula IN também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top