Pregunta

Estoy jugando con declaraciones preparadas en PHP / PDO. Las consultas básicas funcionan bien, pasando un valor a la cláusula WHERE:

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

Sin embargo, tengo una situación en la que necesito pasar variables para los nombres de campo. Esta consulta (con el enlace apropiado) funciona bien:

SELECT :field FROM episode WHERE id=:id

Este da un error:

SELECT title FROM :field WHERE id=:id

Este no da un error, pero no devuelve filas:

SELECT title FROM episode WHERE :field=:id

Entonces, ¿qué cosas deberían funcionar en las declaraciones preparadas? ¿Puedo 'parametrizar' nombres de campo, nombres de tabla, etc.?

¿Fue útil?

Solución

No puede parametrizar nombres de tablas, nombres de columnas ni nada en una cláusula IN (gracias a c0r0ner por señalando la restricción de la cláusula IN ).

Consulte esta pregunta , y posteriormente este comentario en el manual de PHP .

Otros consejos

@ Josh Leitzel

Ese pensamiento es muy restrictivo (y en mi opinión es solo una excusa para ser demasiado vago como para implementar una solución robusta), especialmente para estructuras de árbol dinámicas expresadas en una base de datos.

Considere el siguiente ejemplo:

Mi proyecto tiene una estructura lógica:

La jerarquía de una empresa se expresa en términos de entidades. Cada entidad puede ser tratada en el caso general de ser miembro de la jerarquía o como miembro de un nivel específico de la jerarquía. La jerarquía misma se define en una tabla como una rama de un árbol de la siguiente manera:

entity_structure (
   id
   name
   parent_entity_structure_id
);

y las entidades mismas se expresan como:

entities (
   id
   name
   entity_structure_id
   parent_id
);

Para facilitar su uso, he creado un algoritmo que crea una vista plana del árbol. El siguiente ejemplo concreto ilustra lo que quiero decir:

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

Esto daría como resultado la siguiente representación plana:

entity_tree (
   entity_id
   division_id
   area_id
   store_id
)

Las entidades que están en el nivel de división tendrían division_id, area_id y store_id como NULL, un área area_id y store_id como NULL, etc.

Lo bueno de esto es que le permite consultar a todos los hijos de una división usando una declaración similar a la siguiente:

SELECT * FROM entity_tree WHERE division_id = :division_id;

Sin embargo, esto supone que sé el nivel de estructura de la entidad que estoy consultando. Sería bueno hacer:

SELECT * FROM entity_tree WHERE :structure = :entity_id;

Sé que no es difícil determinar el nivel de estructura de una sola entidad, pero supongo que estoy recorriendo una colección de entidades que pueden no estar todas en el mismo nivel. Como es ahora, tengo que construir una consulta separada para cada nivel de la jerarquía, pero si pudiera parametrizar los campos, podría hacer lo siguiente:

$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);
}

resulta en un código más limpio y solo una declaración preparada.

El ejemplo completo no utiliza ninguna entrada del usuario.

Solo algo a tener en cuenta.

No puede parametrizar nada dentro de la cláusula IN también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top