2010-07-10 22 views
8

Nota: esto es con SQLite, aunque espero que el problema esté en el lado Qt.Qt - Cómo vincular un QList a un QSqlQuery con una cláusula "WHERE ... IN"?

En primer lugar, establecer una mesa de base de datos de la herramienta de línea de comandos 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); 

Entonces pongo a prueba mi consulta: (. Los resultados Aquellos Se espera)

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

Entonces ejecuto este código de 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"; 
} 

que imprime esto:

antes
después

se imprimieron No hay filas. Supongo que esto se debe a que no puedo vincular una lista directamente a un marcador de posición en una cláusula "in". ¿Pero hay una manera de hacerlo? No he podido encontrar nada sobre esto.

Respuesta

6

No importa mi pregunta. Creo que lo que estoy tratando de hacer no es posible con declaraciones preparadas, independientemente del marco o RDBMS. Puedes hacer "WHERE x IN (?)", Pero luego el '?' se refiere a un valor único: no puede ser una lista de valores; o puede hacer "WHERE x IN (?,?,?), y cada '?' necesita ser vinculado por separado.

2

He estado buscando una manera de hacer esto también desde hace un tiempo, y Google no fue muy útil. Empecé a jugar con él y resulta que sí es posible, al menos un grado limitado. Lo he probado solo con PostgreSQL, por lo que no sé sobre otros RDBMS. Mi caso solo concierne a las claves enteras, pero teóricamente también debería funcionar para otros tipos.
La forma de hacerlo es construir un array manualmente y se unen a una variable. Digamos que quiero seleccionar varios usuarios por sus id s de una tabla, como SELECT id, firstname, lastname FROM users WHERE id = ANY(:id). Así es como se puede hacer.

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

mecanografiado de memoria, pero debería estar bien. Sé que esta respuesta es muy tarde, pero espero que esta publicación ayude a alguien más allá. Y como se mencionó anteriormente, esto solo funciona con PostgreSQL. Sin embargo, también podría ser posible adaptar esto a otras bases de datos, dependiendo de su compatibilidad con la matriz.

Cuestiones relacionadas