Domanda

Sto giocando con dichiarazioni preparate in PHP / PDO. Le query di base funzionano correttamente, passando un valore alla clausola WHERE:

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

Tuttavia ho una situazione in cui ho bisogno di passare le variabili per i nomi dei campi. Questa query (con associazione appropriata) funziona bene:

SELECT :field FROM episode WHERE id=:id

Questo dà un errore:

SELECT title FROM :field WHERE id=:id

Questo non dà un errore, ma non restituisce righe:

SELECT title FROM episode WHERE :field=:id

Quindi, quali cose dovrebbero funzionare nelle dichiarazioni preparate? Posso "parametrizzare" i nomi dei campi, i nomi delle tabelle e così via?

È stato utile?

Soluzione

Non è possibile parametrizzare nomi di tabelle, nomi di colonne o altro in una clausola IN (grazie a c0r0ner per sottolineando la restrizione della clausola IN ).

Vedi questa domanda e successivamente questo commento nel manuale PHP .

Altri suggerimenti

@ Josh Leitzel

Questo pensiero è molto restrittivo (ed è secondo me solo una scusa per essere troppo pigro per implementare una soluzione robusta), specialmente per le strutture ad albero dinamiche espresse in un database.

Considera il seguente esempio:

Il mio progetto ha una struttura logica:

Una gerarchia aziendale è espressa in termini di entità. Ogni entità può essere trattata nel caso generale di essere un membro della gerarchia o come membro di un livello specifico della gerarchia. La stessa gerarchia è definita in una tabella come un singolo ramo dell'albero come segue:

entity_structure (
   id
   name
   parent_entity_structure_id
);

e le entità stesse sono espresse come:

entities (
   id
   name
   entity_structure_id
   parent_id
);

Per facilità d'uso ho creato un algoritmo che crea una vista piatta dell'albero. Il seguente esempio concreto illustra cosa intendo:

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

Ciò comporterebbe la produzione della seguente rappresentazione piatta:

entity_tree (
   entity_id
   division_id
   area_id
   store_id
)

Le entità a livello di divisione avrebbero division_id, area_id e store_id come NULL, Un'area area_id e store_id come NULL, ecc.

La cosa bella di questo è che ti permette di interrogare tutti i figli di una divisione usando un'istruzione simile alla seguente:

SELECT * FROM entity_tree WHERE division_id = :division_id;

Tuttavia, questo presuppone che io conosca il livello di struttura dell'entità che sto interrogando. Sarebbe bello da fare:

SELECT * FROM entity_tree WHERE :structure = :entity_id;

So che non è difficile capire il livello di struttura di una singola entità, ma suppongo che sto attraversando un insieme di entità che potrebbero non essere tutte allo stesso livello. Così com'è adesso devo creare una query separata per ogni livello della gerarchia, ma se potessi parametrizzare i campi potrei fare quanto segue:

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

risultante in un codice più pulito e una sola istruzione preparata.

L'intero esempio non utilizza alcun input dell'utente.

Solo qualcosa da considerare.

Non è possibile parametrizzare nulla all'interno della clausola IN .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top