Esistono diverse librerie di builder di query in stile ActiveRecord. Alcuni sono stand alone e alcuni vengono built into frameworks. Tuttavia, hanno davvero problemi con le clausole WHERE e HAVING quando si tratta di SQL complesso. Mettendo da parte altri database, sto cercando di trovare un metodo WHERE() compatibile con MySQL e PostgreSQL che possa risolvere questi problemi attuali.Gestione di clausole WHERE complesse con un generatore di query PHP
Quello che segue è un lungo elenco di idee ed esempi che mostrano il meglio che ho potuto inventare finora. Tuttavia, non riesco a risolvere tutti i casi d'uso e ritengo che la mia soluzione parziale sia sciatta. Chiunque sia in grado di rispondere con qualcosa che risolva tutti questi problemi non solo risponderà a questa domanda, ma sarà responsabile della risoluzione di un problema che ha perseguito le implementazioni PHP per diversi anni.
Operatori comuni
= Equal
<> Not Equal
> Greater Than
< Less Than
>= Greater Than Or Equal
<= Less Than Or Equal
BETWEEN between values on right
NOT logical NOT
AND logical AND
OR logical OR
esempio in cui le clausole
SELECT ... FROM table...
WHERE column = 5
WHERE column > 5
WHERE column IS NULL
WHERE column IN (1, 2, 3)
WHERE column NOT IN (1, 2, 3)
WHERE column IN (SELECT column FROM t2)
WHERE column IN (SELECT c3 FROM t2 WHERE c2 = table.column + 10)
WHERE column BETWEEN 32 AND 34
WHERE column BETWEEN (SELECT c3 FROM t2 WHERE c2 = table.column + 10) AND 100
WHERE EXISTS (SELECT column FROM t2 WHERE c2 > table.column)
Ci sono molti formati comuni ActiveRecord che la clausola in cui() utilizza nelle diverse attuali biblioteche.
$this->db->where(array('session_id' => '?', 'username' => '?'));
$this->db->fetch(array($id, $username));
// vs with is_int($key)
$this->db->where(array('session_id', 'username'));
$this->db->fetch(array($id, $username));
// vs with is_string($where)
$this->db->where('session_id', '?');
$this->db->where('username');
$this->db->fetch(array($id, $username));
// vs with is_array($value)
$this->db->where('session_id', '?');
$this->db->where('username', array('Sam', 'Bob'));
$this->db->fetch(array($id));
Ecco il formato finale che ho finora. Dovrebbe gestire il raggruppamento (...) AND (...)
e i parametri associati alle istruzioni preparate ("?" & ": name").
function where($column, $op = '=', $value = '?', $group = FALSE){}
// Single line
$this->db->where('column > 5');
$this->db->where('column IS NULL');
// Column + condition
$this->db->where('column', '=');
// WHERE column = ? (prepared statement)
$this->db->where('column', '<>');
// WHERE column <> ? (prepared statement)
// Column + condition + values
$this->db->where('column', '=', 5);
// // WHERE column = 5
$this->db->where('column', 'IN', '(SELECT column FROM t2)');
// WHERE column IN (SELECT column FROM t2)
$this->db->where('column', 'IN', array(1,2,3));
// WHERE column IN (1, 2, 3)
$this->db->where('column', 'NOT IN', array(1,2,3));
// WHERE column NOT IN (1, 2, 3)
// column + condition + values + group
$this->db->where(
array(
array('column', '<', 20),
array('column', '>', 10)
),
NULL,
NULL,
$group = TRUE
);
// WHERE (column < 20 AND column > 10)
: UPDATE:
Nel corso della mia domanda mi è venuto a rendersi conto che WHERE e condizioni avendo solo diventano più complessi il più profondo si va. Cercando di astrarre anche l'80% delle funzionalità risulterebbe in una libreria enorme solo per DOVE e AVERE. Come sottolinea Bill, questo non è ragionevole per un linguaggio di scripting come PHP.
La soluzione è solo per creare manualmente la parte WHERE della query. Finché si utilizza "
attorno alle colonne, è possibile utilizzare la stessa query WHERE in Postgre, SQLite e MySQL poiché utilizzano quasi la stessa sintassi SQL. (Per MySQL devi str_replace()
con un segno di spunta`).
Arriva un punto in cui l'astrazione fa più male che aiuta, DOVE le condizioni sono uno di questi luoghi.
Ho la sensazione che sia giusto. Più cerchiamo di astrarre alcune cose, più difficile diventa il nostro lavoro. Un esempio calzante è l'uso forzato di BBCode, tessile o markdown perché i programmatori non volevano filtrare correttamente l'HTML. – Xeoncross
Ho pensato che esistono formati di markup semplici perché gli utenti tipici non possono bilanciare i loro tag HTML. :) –
In realtà, hai * * * per '[b] bilanciare [/ b]' il tuo ' comunque '. È solo che i primi programmatori non capivano la codifica e/o l'uscita dall'output, quindi non sapevano cosa fare con l'HTML nei commenti - * così l'hanno cancellato e gli utenti hanno imparato qualcos'altro *! –
Xeoncross