2010-07-10 39 views
8

注意:这是与SQLite,但我期望问题是在Qt端。Qt - 如何使用“WHERE ... IN”子句将QList绑定到QSqlQuery?

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

然后测试我的查询:

首先,我从SQLite的命令行工具建立一个数据库表(这些预期结果)

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

然后我运行这个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"; 
} 

它打印此:被印无行

之前

。我认为这是因为我无法直接将列表绑定到“in”子句中的占位符。但有没有办法做到这一点?我一直无法找到任何关于此的信息。

回答

6

别管我的问题。我认为,无论框架或RDBMS如何,我所做的都无法用预先准备的语句来完成。你可以做“WHERE x IN(?)”,但是那个'?'指的是单个值 - 它不能是一个值列表;或者你可以做“WHERE x IN(?,?,?),每个'?'需要分开绑定

2

我一直在寻找一种方法来做到这一点,现在Google也不是很有帮助,我开始玩弄它,事实证明它确实有可能,至少在有限的程度上,我只用PostgreSQL进行了测试,所以我不知道其他的RDBMS。我的例子只涉及整数键,但理论上也适用于其他类型的键。
做到这一点的方法是建立一个阵列手动并将其绑定到一个变量。说我要选择多个用户通过他们的id期从一个表,如SELECT id, firstname, lastname FROM users WHERE id = ANY(:id)。下面是它如何可以做到的。

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

从内存中键入,但应该没问题。我知道这个回复非常晚,但希望这篇文章能够帮助别人。如前所述,这只适用于PostgreSQL。但是,也可以根据阵列支持情况将其适用于其他数据库。