Saya memiliki daftar python, katakanlah l
l = [1,5,8]
Saya ingin menulis kueri sql untuk mendapatkan data untuk semua elemen daftar, katakanlah
select name from students where id = |IN THE LIST l|
Bagaimana saya melakukannya?
Saya memiliki daftar python, katakanlah l
l = [1,5,8]
Saya ingin menulis kueri sql untuk mendapatkan data untuk semua elemen daftar, katakanlah
select name from students where id = |IN THE LIST l|
Bagaimana saya melakukannya?
Jawaban:
Jawaban sejauh ini telah membuat template nilai menjadi string SQL biasa. Itu baik-baik saja untuk integer, tetapi jika kita ingin melakukannya untuk string kita mendapatkan masalah escaping.
Berikut adalah varian yang menggunakan kueri berparameter yang akan berfungsi untuk keduanya:
placeholder= '?' # For SQLite. See DBAPI paramstyle.
placeholders= ', '.join(placeholder for unused in l)
query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders
cursor.execute(query, l)
([placeholder]*len(l))dalam kasus umum karena tempat penampung dapat terdiri dari banyak karakter.
cursor.execute(f'SELECT name FROM students WHERE id IN ({','.join('?' for _ in l)})', l) . @bobince, Anda juga harus berkomentar dalam solusi Anda bahwa menggunakan ?adalah cara yang aman untuk menghindari injeksi SQL. Ada banyak jawaban di sini yang rentan, pada dasarnya semua yang menggabungkan string dengan python.
Cara termudah adalah dengan mengubah daftar menjadi yang tuplepertama
t = tuple(l)
query = "select name from studens where id IN {}".format(t)
Jangan mempersulit, Solusi untuk ini sederhana.
l = [1,5,8]
l = tuple(l)
params = {'l': l}
cursor.execute('SELECT * FROM table where id in %(l)s',params)
Saya harap ini membantu !!!
lhanya berisi satu elemen, Anda akan berakhir dengan id IN (1,). Yang merupakan kesalahan sintaks.
sqlite3. Perpustakaan apa yang Anda uji ini?
SQL yang Anda inginkan adalah
select name from studens where id in (1, 5, 8)
Jika Anda ingin membuat ini dari python, Anda dapat menggunakan
l = [1, 5, 8]
sql_query = 'select name from studens where id in (' + ','.join(map(str, l)) + ')'
Fungsi peta akan mengubah daftar menjadi daftar string yang dapat direkatkan dengan koma menggunakan metode str.join .
Kalau tidak:
l = [1, 5, 8]
sql_query = 'select name from studens where id in (' + ','.join((str(n) for n in l)) + ')'
jika Anda lebih suka ekspresi generator daripada fungsi peta.
UPDATE: S. Lott menyebutkan di komentar bahwa binding Python SQLite tidak mendukung urutan. Dalam hal ini, Anda mungkin ingin
select name from studens where id = 1 or id = 5 or id = 8
Dihasilkan oleh
sql_query = 'select name from studens where ' + ' or '.join(('id = ' + str(n) for n in l))
string. Bergabunglah dengan nilai daftar yang dipisahkan dengan koma, dan gunakan operator format untuk membentuk string kueri.
myquery = "select name from studens where id in (%s)" % ",".join(map(str,mylist))
(Terima kasih, blair-conrad )
%digunakan di sini hanyalah pemformatan string Python biasa.
Saya suka jawaban bobince:
placeholder= '?' # For SQLite. See DBAPI paramstyle.
placeholders= ', '.join(placeholder for unused in l)
query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders
cursor.execute(query, l)
Tapi saya perhatikan ini:
placeholders= ', '.join(placeholder for unused in l)
Bisa diganti dengan:
placeholders= ', '.join(placeholder*len(l))
Saya menemukan ini lebih langsung jika kurang pintar dan kurang umum. Di sini ldiperlukan untuk memiliki panjang (yaitu merujuk ke objek yang mendefinisikan __len__metode), yang seharusnya tidak menjadi masalah. Tapi placeholder juga harus satu karakter. Untuk mendukung penggunaan placeholder multi-karakter:
placeholders= ', '.join([placeholder]*len(l))
Solusi untuk jawaban @umounted, karena itu putus dengan tupel satu elemen, karena (1,) bukan SQL yang valid .:
>>> random_ids = [1234,123,54,56,57,58,78,91]
>>> cursor.execute("create table test (id)")
>>> for item in random_ids:
cursor.execute("insert into test values (%d)" % item)
>>> sublist = [56,57,58]
>>> cursor.execute("select id from test where id in %s" % str(tuple(sublist)).replace(',)',')'))
>>> a = cursor.fetchall()
>>> a
[(56,), (57,), (58,)]
Solusi lain untuk string sql:
cursor.execute("select id from test where id in (%s)" % ('"'+'", "'.join(l)+'"'))
placeholders= ', '.join("'{"+str(i)+"}'" for i in range(len(l)))
query="select name from students where id (%s)"%placeholders
query=query.format(*l)
cursor.execute(query)
Ini seharusnya menyelesaikan masalah Anda.
Jika Anda menggunakan PostgreSQL dengan pustaka Psycopg2, Anda dapat membiarkan adaptasi tupelnya melakukan semua pelolosan dan interpolasi string untuk Anda, misalnya:
ids = [1,2,3]
cur.execute(
"SELECT * FROM foo WHERE id IN %s",
[tuple(ids)])
yaitu, pastikan Anda meneruskan INparameter sebagai a tuple. jika itu adalah listAnda dapat menggunakan = ANYsintaks array :
cur.execute(
"SELECT * FROM foo WHERE id = ANY (%s)",
[list(ids)])
perhatikan bahwa keduanya akan diubah menjadi rencana kueri yang sama sehingga Anda sebaiknya menggunakan mana saja yang lebih mudah. misalnya jika daftar Anda datang dalam bentuk tupel, gunakan yang pertama, jika mereka disimpan dalam daftar, gunakan yang terakhir.
Misalnya, jika Anda menginginkan kueri sql:
select name from studens where id in (1, 5, 8)
Bagaimana dengan:
my_list = [1, 5, 8]
cur.execute("select name from studens where id in %s" % repr(my_list).replace('[','(').replace(']',')') )
solusi yang lebih sederhana:
lst = [1,2,3,a,b,c]
query = f"""SELECT * FROM table WHERE IN {str(lst)[1:-1}"""
l = [1] # or [1,2,3]
query = "SELECT * FROM table WHERE id IN :l"
params = {'l' : tuple(l)}
cursor.execute(query, params)
The :varnotasi tampaknya sederhana. (Python 3.7)
Ini menggunakan substitusi parameter dan menangani kasus daftar nilai tunggal:
l = [1,5,8]
get_operator = lambda x: '=' if len(x) == 1 else 'IN'
get_value = lambda x: int(x[0]) if len(x) == 1 else x
query = 'SELECT * FROM table where id ' + get_operator(l) + ' %s'
cursor.execute(query, (get_value(l),))
','.join(placeholder * len(l))akan menjadi sedikit lebih pendek sementara masih dapat dibaca imho