QT - QLIST를 "어디에서 in"절에서 QSQLQUERY에 바인딩하는 방법?
-
13-09-2020 - |
문제
참고 : 문제가 Qt 측면에 있음을 기대하지만 SQLite는 SQLite입니다.
첫째, 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);
.
다음 내 쿼리를 테스트합니다.
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";
}
.
이 this :
후에
행이 인쇄되지 않았습니다.목록을 "in"절의 자리 표시 자에게 직접 바인딩 할 수 없기 때문입니다.그러나 그것을 할 수있는 방법이 있습니까?나는 이것에 대해 아무것도 찾을 수 없었습니다.
해결책
내 질문을 신경 쓰지 마십시오.나는 프레임 워크 나 RDBMS에 관계없이 준비된 진술로 할 수없는 것을 생각하는 것이 불가능합니다.당신은 "x in (?)"을 할 수는 있지만 '?'단일 값을 나타냅니다 - 값 목록이 될 수 없습니다.또는 "X in (?,?,?), 각각 '?'할 수 있습니다.별도로 바인딩해야합니다.
예 :
QString const queryText = "SELECT id, firstname FROM users WHERE id IN (%1)";
QVector<int> const ids { /* ... */ };
QVector<QString> const placeholders(ids.size(), "?");
QSqlQuery query(db);
query.prepare(queryText.arg(QStringList::fromVector(placeholders).join(", ")));
for (auto const & i : ids)
query.addBindValue(i);
query.exec();
. 다른 팁
나는 지금 까지이 일을 할 수있는 방법을 찾고 있으며, Google은별로 도움이되지 않았습니다.나는 그것으로 놀기 시작했고, 적어도 제한된 정도로 실제로 가능하다는 것이 밝혀졌습니다.PostgreSQL 및 SQLite에서만 테스트되므로 다른 RDBMS에 대해 알지 못합니다.내 사건은 정수 키 만 관련이 있지만 이론적으로 다른 유형을 위해 작동해야합니다.
이렇게하는 방법은 수동으로 배열을 빌드하고 변수에 바인딩합니다.id
와 같은 테이블에서 SELECT id, firstname, lastname FROM users WHERE id = ANY(:id)
s로 여러 사용자를 선택하고 싶습니다.다음은 어떻게 할 수 있는지 있습니다.
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", numberlist);
sql.exec();
// Now this is possible
while( sql.next() ) {
qDebug() << sql.value(0).toInt() << sql.value(1).toString() << sql.value(2).toString();
}
.
메모리에서 입력하지만 괜찮을 것입니다.나는이 답변이 매우 늦었지만,이 게시물은 다른 누군가가 밖에있는 것을 돕는 것을 알고 있습니다.위의 스 니펫은 PostgreSQL에서만 작동합니다.그러나 배열 지원에 따라 다른 데이터베이스도 다른 데이터베이스에 적용 할 수 있습니다.
SQLite의 경우 SQL 쿼리를 다음과 같이 바꿉니다.
sql.prepare("SELECT id, firstname, lastname FROM users WHERE id IN (:id)");
.