2010-07-10 4 views
8

Note: c'est avec SQLite, même si je pense que le problème est du côté de Qt.Qt - Comment lier une QList à une QSqlQuery avec une clause "WHERE ... IN"?

D'abord, je mis en place une table de base de données de l'outil de ligne de commande SQLite:

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

Puis-je tester ma requête: (. Ceux-ci sont les résultats attendus)

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

Ensuite, je lance ce code 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"; 
} 

qui imprime ceci:

avant
après

Aucune ligne n'a été imprimées. Je suppose que c'est parce que je ne peux pas lier une liste directement à un espace réservé dans une clause "in". Mais y a-t-il un moyen de le faire? Je n'ai pas été capable de trouver quoi que ce soit à ce sujet.

Répondre

6

Ne t'occupe pas de ma question. Je pense que ce que j'essaie de faire n'est pas possible avec les déclarations préparées, indépendamment du cadre ou du SGBDR. Vous pouvez faire "WHERE x IN (?)", Mais le "?" fait référence à une seule valeur - il ne peut pas s'agir d'une liste de valeurs; ou vous pouvez faire "WHERE x IN (?,?,?), et chaque '?'

2

Cela faisait un moment que je cherchais un moyen de le faire aussi, et Google n'a pas été très utile, j'ai commencé à jouer avec et il s'avère effectivement possible de Je l'ai testé uniquement avec PostgreSQL, donc je ne connais pas d'autres SGBDR, mon cas ne concerne que les clés entières, mais devrait aussi théoriquement fonctionner pour d'autres types. tableau et lier manuellement à une variable. Disons que je veux sélectionner plusieurs utilisateurs par leurs id s d'une table, comme SELECT id, firstname, lastname FROM users WHERE id = ANY(:id). Voici comment il peut être fait.

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

Typed de la mémoire, mais devrait être bien. Je sais que cette réponse est extrêmement tardive, mais j'espère que ce message aidera quelqu'un d'autre. Et comme mentionné précédemment, cela ne fonctionne qu'avec PostgreSQL. Cependant, il pourrait être possible de l'adapter à d'autres bases de données, en fonction de leur support.

Questions connexes