Pergunta

Nota:isso é com o SQLite, apesar de eu esperar que o problema é no Qt lado.

Primeiro, eu configurar uma tabela de banco de dados do SQLite ferramenta de linha de comando:

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

Em seguida, testar a minha consulta:

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

(Esses são os resultados esperados.)

Então eu executar esse código 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";
}

que imprime a este:

antes de
depois de

Não há linhas foram impressas.Suponho que isso é porque eu não posso ligar uma lista diretamente para um espaço reservado em um "na" cláusula.Mas existe uma maneira de fazê-lo?Eu não tenho sido capaz de encontrar nada sobre isso.

Foi útil?

Solução

Não importa a minha pergunta.Eu acho que o que eu estou tentando fazer é que não é possível com instruções preparadas, independentemente da estrutura ou RDBMS.Você pode fazer ", ONDE x EM (?)", mas, em seguida, o '?' refere-se a um único valor -- ele não pode ser uma lista de valores;ou você pode fazer ", ONDE x EM (?,?,?), e cada"? " precisa ser ligado separadamente.

Exemplo:

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

Outras dicas

Eu tenho procurado uma maneira de fazer isso também, por um tempo agora, e o Google não era muito útil.Eu comecei a brincar com ele e o que acontece na verdade, é possível, até certo ponto, pelo menos.Ele é testado apenas com o PostgreSQL e SQLite, então eu não sei sobre outros RDBMS.Meu caso refere-se apenas de inteiro chaves, mas teoricamente deve funcionar para outros tipos também.
A maneira de fazer isso é construir uma matriz manualmente e vinculá-lo a uma variável.Digamos que eu queira selecionar vários usuários através de seus ids a partir de uma tabela, tal como SELECT id, firstname, lastname FROM users WHERE id = ANY(:id).Veja como isso pode ser feito.

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

Escrito a partir da memória, mas deve ser fino.Eu sei que esta resposta é extremamente atrasado, mas espero que este post ajude alguém lá fora.O trecho acima só funciona com o PostgreSQL.No entanto, é possível adaptar isso para outros bancos de dados, bem como, dependendo da sua matriz de suporte.

Para o SQLite substituir a consulta SQL com:

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

Você tem que usar 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();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top