2013-02-23 28 views
12

Tôi đang cố gắng để thực hiện một truy vấn theo hình thức ..."SELECT ... WHERE ... IN" với số lượng không rõ các thông số

SELECT col2 FROM tab WHERE col1 IN (val1, val2, val3...) 

... nơi các giá trị được lưu trữ trong một danh sách Python/tuple có độ dài tùy ý. Tôi dường như không thể tìm thấy một cách "sạch" để làm điều đó.

>>> db = connect(":memory:") 
>>> db.execute("CREATE TABLE tab (col1 INTEGER, col2 TEXT)") 
>>> db.execute("INSERT INTO tab VALUES(1,'one')") 
>>> db.execute("INSERT INTO tab VALUES(2,'two')") 
>>> db.execute("INSERT INTO tab VALUES(3,'three')") 
>>> db.execute("INSERT INTO tab VALUES(4,'four')") 
>>> db.execute("INSERT INTO tab VALUES(5,'five')") 
>>> db.commit() 

# Expected result 
>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (1,3,4)").fetchall() 
[(u'one',), (u'three',), (u'four',)] 

>>> vals = (1,3,4) 

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (?)", vals).fetchall() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 3 supplied. 

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (?)", (vals,)).fetchall() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type. 

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (?)", (','.join(str(val) for val in vals),)).fetchall() 
[] 

>>> 

Bây giờ tôi có thể làm những điều sau đây, trong đó (tôi nghĩ ... hãy sửa lại cho tôi nếu tôi sai) vẫn giữ được sự an toàn của các built-in thay thế tham số, nhưng nó vẫn còn một chút xấu xí:

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (" + ",".join("?"*len(vals)) + ")", vals).fetchall() 
[(u'one',), (u'three',), (u'four',)] 
>>> 

Đó có phải là lựa chọn tốt nhất của tôi hoặc có cách nào đẹp hơn xung quanh vấn đề này không?

+0

bản sao có thể có của [SQLite: danh sách liên kết các giá trị thành "WHERE col IN (: PRM)"] (http://stackoverflow.com/questions/4788724/sqlite-bind-list-of-values-to-where -col-in-prm) – rsaxvc

Trả lời

6

Đó là lựa chọn tốt nhất của bạn mà không sử dụng thư viện bổ sung. Tôi chắc chắn có advocated just that technique trong quá khứ, more than once trên thực tế.

Bạn cũng có thể chuyển sang sử dụng SQLAlchemy, tạo SQL cho bạn, nhưng yêu cầu bạn phải leo lên đường cong học tập của nó và viết lại hầu hết ứng dụng của bạn.

+0

Đủ công bằng, cảm ơn. Đây là một điều khó tìm kiếm vì các thuật ngữ quan trọng là những từ thông dụng ... – glibdud

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