Qt - Как связать QList к QSQLQUERY с предложением «Где ... в»?

StackOverflow https://stackoverflow.com/questions/3220357

  •  13-09-2020
  •  | 
  •  

Вопрос

Примечание. Это с SQLite, хотя я ожидаю, что проблема на стороне QT.

Во-первых, я настроил таблицу базы данных из инструмента командной строки 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";
}
.

Что печатает это:

перед

после

Ни одна строка не были напечатаны.Я предполагаю, что это потому, что я не могу связать список непосредственно к заполнителю в пункте «в».Но есть ли способ сделать это?Я не смог ничего найти об этом.

Это было полезно?

Решение

Неважно не возражаю на мой вопрос.Я думаю, что я пытаюсь сделать, это невозможно с подготовленными заявлениями, независимо от структуры или RDBMS.Вы можете сделать «где X в (?)», Но потом «?»относится к одному значению - он не может быть списком значений;Или вы можете сделать «Где X в (?,?,?), И каждый«? »должен быть связан отдельно.

Пример:

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.Мой дело касается только целочисленных ключей, но следует также теоретически работать для других типов.
Способ сделать это создает массив вручную и связывает его с переменной.Скажем, я хочу выбрать несколько пользователей по своим генеракодицетамCodes из таблицы, такой как 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", 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)");
.

Вы должны использовать qsqlquery :: exchbatch >

QSqlQuery q;
q.prepare("insert into myTable values (?, ?)");

QVariantList ints;
ints << 1 << 2 << 3 << 4;
q.addBindValue(ints);

QVariantList names;
names << "Harald" << "Boris" << "Trond" << QVariant(QVariant::String);
q.addBindValue(names);

if (!q.execBatch())
    qDebug() << q.lastError();
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top