2010-07-10 10 views
8

Uwaga: dotyczy to SQLite, chociaż spodziewam się, że problem dotyczy strony Qt.Qt - Jak powiązać QList z QSqlQuery za pomocą klauzuli "WHERE ... IN"?

Najpierw utwórz tabelę bazy danych z SQLite narzędzia wiersza poleceń:

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

Potem przetestować moje zapytanie: (. Ci są spodziewane wyniki)

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

Następnie uruchamiam ten kod 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"; 
} 

która drukuje to:

przed
po

Brak wiersze były drukowane. Zakładam, że dzieje się tak dlatego, że nie mogę powiązać listy bezpośrednio z elementem zastępczym w klauzuli "w". Ale czy istnieje sposób, aby to zrobić? Nie byłem w stanie znaleźć niczego na ten temat.

Odpowiedz

6

Nie zwracajcie uwagi na moje pytanie. Myślę, że to, co próbuję zrobić, nie jest możliwe przy przygotowanych stwierdzeniach, niezależnie od frameworka lub RDBMS. Możesz zrobić "WHERE x IN (?)", Ale wtedy "?" odnosi się do pojedynczej wartości - nie może być listą wartości; lub możesz zrobić "WHERE x IN (?,?,?) i każdy"? " musi być związany osobno:

2

Od pewnego czasu szukam sposobu, aby to zrobić, a Google nie był bardzo pomocny. Zacząłem grać z nim i okazało się, że jest to możliwe, aby przynajmniej w ograniczonym stopniu. Przetestowałem go tylko z PostgreSQL, więc nie wiem o innych RDBMS, mój przypadek dotyczy tylko kluczy całkowitych, ale teoretycznie powinien działać także dla innych typów.
Sposób na to jest zbudowanie tablica ręcznie i powiązać go do zmiennej. Załóżmy, chcę zaznaczyć wielu użytkowników przez ich id s z tabeli, takie jak SELECT id, firstname, lastname FROM users WHERE id = ANY(:id). Oto jak można to zrobić.

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", QString("{%1}").arg(numberlist)); 
sql.exec(); 

// Now this is possible 
while(sql.next()) { 
    qDebug() << sql.value(0).toInt() << sql.value(1).toString() << sql.value(2).toString(); 
} 

Wpisywane z pamięci, ale powinno być w porządku. Wiem, że ta odpowiedź jest bardzo późna, ale mam nadzieję, że ten post pomoże komuś innemu. Jak wspomniano wcześniej, działa to tylko z PostgreSQL. Jednak może być możliwe dostosowanie tego również do innych baz danych, w zależności od ich obsługi macierzy.

Powiązane problemy