Question

Je m'amuse avec les instructions préparées en PHP / PDO. Les requêtes de base fonctionnent correctement et transmettent une valeur à la clause WHERE:

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

Cependant, je dois parfois passer des variables pour les noms de champs. Cette requête (avec la liaison appropriée) fonctionne correctement:

SELECT :field FROM episode WHERE id=:id

Celui-ci donne une erreur:

SELECT title FROM :field WHERE id=:id

Celui-ci ne génère pas d'erreur, mais ne renvoie aucune ligne:

SELECT title FROM episode WHERE :field=:id

Alors, quels éléments devraient fonctionner dans les déclarations préparées? Puis-je "paramétrer" les noms de champs, les noms de tables, etc.?

Était-ce utile?

La solution

Vous ne pouvez pas paramétrer les noms de table, les noms de colonne ou quoi que ce soit dans une clause IN (merci à c0r0ner pour en soulignant la restriction de la clause IN ).

Voir cette question , et ce commentaire dans le manuel PHP .

Autres conseils

@ Josh Leitzel

Cette pensée est très restrictive (et n’est à mon avis qu’une excuse pour être trop paresseuse pour mettre en œuvre une solution robuste), en particulier pour les arborescences dynamiques exprimées dans une base de données.

Prenons l'exemple suivant:

Mon projet a une structure logique:

Une hiérarchie d'entreprise est exprimée en termes d'entités. Chaque entité peut être traitée dans le cas général d’être membre de la hiérarchie ou en tant que membre d’un niveau spécifique de la hiérarchie. La hiérarchie elle-même est définie dans une table comme une branche d'arbre unique, comme suit:

entity_structure (
   id
   name
   parent_entity_structure_id
);

et les entités elles-mêmes sont exprimées comme suit:

entities (
   id
   name
   entity_structure_id
   parent_id
);

Pour faciliter l’utilisation, j’ai construit un algorithme qui crée une vue plane de l’arbre. L'exemple concret suivant illustre ce que je veux dire:

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

Cela produirait la représentation plate suivante:

entity_tree (
   entity_id
   division_id
   area_id
   store_id
)

Les entités qui se trouvent au niveau de la division auraient division_id, area_id et store_id en tant que NULL, An area area_id et store_id en tant que NULL, etc.

La bonne chose à ce sujet est qu’il vous permet d’interroger tous les enfants d’une division en utilisant une instruction similaire à celle-ci:

SELECT * FROM entity_tree WHERE division_id = :division_id;

Toutefois, cela suppose que je connaisse le niveau de structure de l'entité interrogée. Ce serait bien de faire:

SELECT * FROM entity_tree WHERE :structure = :entity_id;

Je sais que ce n'est pas difficile de déterminer le niveau de structure d'une seule entité, mais supposons que je parcours en boucle une collection d'entités qui peuvent ne pas toutes être au même niveau. En l'état actuel des choses, je dois créer une requête distincte pour chaque niveau de la hiérarchie, mais si je pouvais paramétrer les champs, je pourrais procéder comme suit:

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

résultant en un code plus propre et une seule instruction préparée.

L'ensemble de l'exemple n'utilise aucune entrée de l'utilisateur.

Juste quelque chose à considérer.

Vous ne pouvez rien paramétrer dans la clause IN également.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top