I am running python with the sqlite3 module and would like to search for rows that match a list. The sql should look like
SELECT column FROM table WHERE column IN (1, 2, 3, 4, 5)
In python, we are recommended to use the ?
parameter for value substitution, so this should look like
val_num = [ 1, 2, 3, 4, 5 ]
val_str = ', '.join( [ str(v) for v in val_num ] )
db = sqlite3.connect( filename )
sql = '''SELECT column FROM table WHERE column IN (?)'''
cur = db.cursor()
cur.execute( sql, (val_str,) )
print( cur.fetch_all() )
cur.close()
This returns an empty list, []
However, if I manually substitute values into the sql statement, which is not advised, it works as expected
val_num = [ 1, 2, 3, 4, 5 ]
val_str = ', '.join( [ str(int(v)) for v in val_num ] )
db = sqlite3.connect( filename )
sql = '''SELECT column FROM table WHERE column IN ({})'''.format( val_str )
cur = db.cursor()
cur.execute( sql, (val_str,) )
print( cur.fetch_all() )
cur.close()
Which returns [(1,), (2,), (3,), (4,), (5,)]
How do I execute this statement using the API syntax instead of manually substituting values?
Try to use this approach to make the IN
operation :
val_num = [ 1, 2, 3, 4, 5 ]
query_str = '''
SELECT column FROM table
where
column in (
''' + ','.join('%s' for i in range(len(val_num))) + ' ) '
cursor.execute(query_str, params=tuple(val_num))
rows = cursor.fetchall()
This is the pseudo-code , not given the statements to make cursor
objects n all. just try to change your query-string
& the execute
line seeing this example - you will get it working.
The placeholder mechansim is here to pass single literal values, not lists. So this:
SELECT column FROM table WHERE column IN (?)
... generates a query where all values are stuffed together in the same literal string, like:
SELECT column FROM table WHERE column IN ('1, 2, 3, 4, 5')
The where
predicate is equivalent to: column = '1, 2, 3, 4, 5'
, which obviously is not what you want.
You need have one placeholder ( ?
) per value in the list. Here is one way to do it:
sql = 'SELECT column FROM table WHERE column IN ({0})'.format(', '.join('?' for _ in val_num));
cur.execute(sql, val_num);
If the goal is to use server-side parameter substitution you will need to build the query to have the exact amount of ?
that you have variables you want to check. The following should achieve that.
val_num = [1, 2, 3, 4, 5]
qs = ", ".join("?" * len(val_num))
query = f"SELECT column FROM table WHERE column IN {qs}"
cur.execute(sql, val_str)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.