2013-01-11 28 views
6

tôi đã cố gắngsqlquery một tên giữ chỗ nhiều lần

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

giả định rằng idVal sẽ được binded hai lần, nhưng thực hiện truy vấn này chỉ hàng với id_parent = idVal bị xóa, với id_col = idVal vẫn xóa được. Vì vậy, chỉ có idVal thời gian thứ hai được liên kết với truy vấn.

Khi tôi viết lại nó để

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

tất cả mọi thứ đã làm việc như mong đợi.

Đây có phải là cách để sử dụng một trình giữ chỗ được đặt tên nhiều lần trong QSqlQuery không?

+1

** Lưu ý phụ: ** Điều này không trả lời cho bạn câu hỏi, nhưng bạn có thể 'THAM GIA 'bằng cách xóa và chỉ sử dụng một trình giữ chỗ. Một cái gì đó như: 'DELETE n FROM tên n INNER JOIN tên p ON p.id_col = n.id_parent WHERE id_col =: ID'. –

+2

Đối với hậu thế, tôi tìm thấy một hack cho một vấn đề liên quan khi bạn đang làm _select_ báo cáo. Sử dụng ['with clause'] (https://www.sqlite.org/lang_with.html) như sau:' with my_id as (values ​​(: id)) chọn * từ tên id = (select * from my_id) hoặc parent_id = (chọn * từ my_id) ' –

+0

* ngớ ngẩn *: Ràng buộc này được loại bỏ trong qt 5, do đó, các giải pháp thay thế chỉ cần thiết trước qt 5. –

Trả lời

3

Từ QSqlQuery::bindValue() documentation:

Giá trị không thể bị ràng buộc với nhiều vị trí trong truy vấn, ví dụ:

INSERT INTO testtable (id, name, samename) VALUES (: id, tên,: tên)

Binding tên sẽ liên kết với người đầu tiên: tên, nhưng không phải là thứ hai.

Câu cuối cùng có vẻ hơi sai vì có vẻ như nó liên kết với tên thứ hai, nhưng theo cách này, điều này nêu rõ những gì bạn đang cố đạt được không được Qt hỗ trợ.

Tùy chọn của bạn là gắn bó với giải pháp thay thế mà bạn đã có hoặc sử dụng giải pháp được cung cấp bởi Mahmoud Gamal trong nhận xét cho câu hỏi của bạn.

+1

Trong tài liệu của Qt 5.9.1 (http: //doc.qt .io/qt-5/qsqlquery.html # bindValue) văn bản này được loại bỏ và nhiều ràng buộc thực sự hoạt động. – scopchanov

0

Hãy thử làm đầu tiên này:

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

nếu ở trên chọn trả lại dữ liệu ngay sau đó sử dụng sau khi truy vấn của bạn:

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

Để xem truy vấn nào thực sự được thực thi, bạn có thể sử dụng QSqlQuery::executedQuery().

Và bạn nên thiết lập một cách rõ ràng giá trị cho placeholders:

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

Ngoài ra nó sẽ hữu ích nếu bạn cần sắp xếp trong tương lai.

Các vấn đề liên quan