18

注:これは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";
}

これを印刷します:

前後
_

行は印刷されませんでした。これは、「in」句でリストをプレースホルダーに直接バインドできないためだと思います。しかし、それを行う方法はありますか?私はこれについて何も見つけることができませんでした。

4

3 に答える 3

9

私の質問を気にしないでください。フレームワークやRDBMSに関係なく、プリペアドステートメントでは私がやろうとしていることは不可能だと思います。「WHERExIN(?)」を実行できますが、「?」単一の値を参照します-値のリストにすることはできません。または、「WHERE 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();
于 2010-07-10T18:38:36.337 に答える
8

私もしばらくの間これを行う方法を探していました、そしてグーグルはあまり役に立ちませんでした。私はそれをいじり始めました、そしてそれは少なくとも限られた程度で、それが確かに可能であることがわかりました。PostgreSQLとSQLiteでのみテストされているので、他のRDBMSについては知りません。私の場合は整数キーのみに関係しますが、理論的には他のタイプでも機能するはずです。
これを行う方法は、配列を手動で作成し、それを変数にバインドすることです。idたとえば、テーブルから複数のユーザーをsで選択したいとします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", 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)");
于 2013-12-16T08:06:16.903 に答える
0

QSqlQuery::execBatchを使用する必要があります

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();
于 2018-10-24T08:45:34.333 に答える