2013-01-11 10 views
6

ho cercatoSQLQuery uno denominati placeholders diverse volte

QSqlQuery query; 
    query.prepare("DELETE FROM names WHERE id_col = :ID OR id_parent = :ID"); 
    query.bindValue(":ID", idVal); 
    query.exec(); 

supponendo che idVal verrà rilegato due volte, ma che esegue la query solo le righe con id_parent = idVal viene eliminato, con id_col = idVal rimane non eliminata. Quindi solo la seconda volta IDVal è stato associato alla query.

Quando io riscrivo a

QSqlQuery query; 
    query.prepare("DELETE FROM names WHERE id_col = ? OR id_parent = ?"); 
    query.bindValue(0, idVal); 
    query.bindValue(1, idVal); 
    query.exec(); 

tutto ha funzionato come previsto.

E 'un modo per utilizzare un segnaposto di nome più volte in QSqlQuery?

+1

** Nota a margine: ** Questo non risponde si mette in discussione, ma è possibile 'JOIN' con delete e utilizzare un solo segnaposto. Qualcosa di simile: 'DELETE FROM n nomi n INNER JOIN nomi p ON p.id_col = n.id_parent DOVE id_col =: ID'. –

+2

Per i posteri, ho trovato un trucco per un problema correlato quando si eseguono le istruzioni _select_. Utilizzare il [ 'con clausola di] (https://www.sqlite.org/lang_with.html) in questo modo:' con my_id come (valori (: id)) select * from nomi dove id = (select * from my_id) o parent_id = (seleziona * da my_id) ' –

+0

* timidamente *: questo vincolo viene rimosso in qt 5, quindi i workaround sono necessari solo prima di qt 5. –

risposta

3

Dal QSqlQuery::bindValue() documentation:

I valori non possono essere associati a più posizioni nella query, ad esempio:

INSERT INTO TestTable (id, nome, samename) VALORI (: id,: nome,: nome)

Binding al nome si legano alla prima: nome, ma non il secondo.

L'ultima frase sembra essere leggermente errata in quanto sembra che si leghi al secondo: nome, ma in entrambi i casi, questo indica chiaramente che cosa stai cercando di ottenere non è supportato da Qt.

Le opzioni disponibili sono di attaccare con la soluzione già avete, o utilizzare la soluzione fornita da Mahmoud Gamal nel commento alla tua domanda.

+1

Nella documentazione di Qt 5.9.1 (http: //doc.qt .io/qt-5/qsqlquery.html # bindValue) questo testo viene rimosso e il binding multiplo funziona davvero. – scopchanov

0

Prova questa prima do:

select * from names where :ID in 
((select id_col FROM names WHERE id_col = :ID) 
OR 
(select id_parent FROM names WHERE id_parent = :ID) 
); 

se quanto sopra selezionare restituito i dati giusti quindi utilizzare il seguente come query:

delete from names where :ID in 
((select id_col FROM names WHERE id_col = :ID) 
OR 
(select id_parent FROM names WHERE id_parent = :ID) 
); 
1

Per vedere cosa interrogazione è stato effettivamente eseguito, è possibile utilizzare QSqlQuery::executedQuery().

E si dovrebbe esplicitamente impostare i valori per i segnaposto:

QSqlQuery query; 
query.prepare("DELETE FROM names WHERE id_col = :ID_COL OR id_parent = :ID_PAR"); 
query.bindValue(":ID_COL", idVal); 
query.bindValue(":ID_PAR", idVal); 
query.exec(); 

Inoltre sarà utile se avrete bisogno di refactoring in futuro.

Problemi correlati