2010-07-10 6 views
8

Nota: questo è con SQLite, anche se mi aspetto che il problema sia sul lato Qt.Qt - Come associare una QList a una QSqlQuery con una clausola "WHERE ... IN"?

In primo luogo, ho creato una tabella di database dalla SQLite strumento da riga di comando:

sqlite> create table testtable (id INTEGER PRIMARY KEY NOT NULL, state INTEGER); 
sqlite> insert into testtable (state) values (0); 
sqlite> insert into testtable (state) values (1); 
sqlite> insert into testtable (state) values (9); 
sqlite> insert into testtable (state) values (20); 

Poi ho testare la mia domanda: (. Risultati Quelli sono attesi)

sqlite> SELECT id,state FROM testtable WHERE state IN (0,1,2); 
1|0 
3|1 

Quindi eseguo questo codice C++:

void runQuery() { 
     QSqlQuery qq; 
     qq.prepare("SELECT id,state FROM testtable WHERE state IN (:states)"); 
     QList<QVariant> statesList = QList<QVariant>(); 
     statesList.append(0); 
     statesList.append(1); 
     statesList.append(2); 
     qq.bindValue(":states", statesList); 
     qq.exec(); 
     qDebug() << "before"; 
     while(qq.next()) { 
      qDebug() << qq.value(0).toInt() << qq.value(1).toInt(); 
     } 
     qDebug() << "after"; 
} 

che stampa questo:

prima
dopo

sono stati stampati Nessuna riga. Presumo questo perché non posso associare una lista direttamente a un segnaposto in una clausola "in". Ma c'è un modo per farlo? Non sono stato in grado di trovare nulla a riguardo.

risposta

6

Non importa la mia domanda. Penso che quello che sto cercando di fare non sia possibile con le dichiarazioni preparate, indipendentemente dal framework o RDBMS. Puoi fare "DOVE x IN (?)", Ma poi "?" si riferisce a un singolo valore: non può essere un elenco di valori; oppure puoi fare "DOVE x IN (?,?,?), e ogni '?'

2

Ho cercato un modo per farlo anche per un po 'di tempo e Google non mi è stato di grande aiuto. Ho iniziato a giocarci e si scopre che è davvero possibile, almeno un livello limitato, l'ho testato solo con PostgreSQL, quindi non conosco altri RDBMS.Il mio caso riguarda solo chiavi intere, ma dovrebbe teoricamente funzionare anche per altri tipi.
Il modo per farlo è costruire un allineamento manualmente e associarlo a una variabile. dire che voglio per selezionare più utenti da parte dei loro id s da una tabella, ad esempio SELECT id, firstname, lastname FROM users WHERE id = ANY(:id). Ecco come si può fare.

QList<int> ids; // A list of IDs to select 
ids << 1 << 5 << 7; 

// Create strings from list 
QStringList idstrings; 
foreach(int id, ids) { 
    idstrings << QString::number(id); 
} 
QString numberlist = idstrings.join(","); 

// Create, prepare and execute the query 
QSqlQuery sql; 
sql.prepare("SELECT id, firstname, lastname FROM users WHERE id = ANY(:id)"); 
sql.bindValue(":id", QString("{%1}").arg(numberlist)); 
sql.exec(); 

// Now this is possible 
while(sql.next()) { 
    qDebug() << sql.value(0).toInt() << sql.value(1).toString() << sql.value(2).toString(); 
} 

Digitato dalla memoria, ma dovrebbe andare bene. So che questa risposta è estremamente tardiva, ma spero che questo post aiuti qualcun altro là fuori. E come detto prima, funziona solo con PostgreSQL. Tuttavia potrebbe essere possibile adattarlo anche ad altri database, a seconda del supporto dell'array.

Problemi correlati