Domanda

Nota: questo è con SQLite, anche se mi aspetto che il problema sia sul lato QT.

In primo luogo, ho impostato una tabella di database dallo strumento della riga di comando 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);
.

Allora metto alla prova la mia query:

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

(quelli sono previsti risultati.)

Allora eseguo questo codice 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";
}
.

Che stampa questo:

.

Prima
Dopo

Nessuna riga è stata stampata.Suppongo che questo sia perché non posso associare un elenco direttamente a un segnaposto in una clausola "in".Ma c'è un modo per farlo?Non sono stato in grado di trovare nulla a riguardo.

È stato utile?

Soluzione

Non importa la mia domanda.Penso che cosa sto cercando di fare non è possibile con dichiarazioni preparate, indipendentemente dal quadro o dal RDBMS.Puoi fare "dove x in (?)", Ma allora il "?"Si riferisce a un singolo valore - non può essere un elenco di valori;o puoi fare "dove x in (?,?,?), E ogni '?'deve essere vincolato separatamente.

Esempio:

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

Altri suggerimenti

Ho cercato un modo per farlo anche per un po 'ora, e Google non era molto utile.Ho iniziato a giocare con esso e si scopre che è davvero possibile, almeno in misura limitata.È testato solo con PostgreSQL e SQLite, quindi non so di altri RDBMS.Il mio caso riguarda solo i tasti interi, ma dovrebbe funzionare teoricamente per altri tipi.

Il modo per farlo è costruire un array manualmente e legarlo a una variabile.Dì che voglio selezionare più utenti dai loro generatori di generatori da una tabella, come id.Ecco come può essere fatto.

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

Digitato dalla memoria, ma dovrebbe andare bene.So che questa risposta è estremamente tardi, ma spero che questo post aiuti a qualcun altro là fuori.Lo snippet sopra funziona solo con PostgreSQL.Tuttavia è possibile adattarsi anche ad altri database, a seconda del loro supporto dell'array.

per SQLite Sostituisci la query SQL con:

sql.prepare("SELECT id, firstname, lastname FROM users WHERE id IN (:id)");
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top