Python FDB подготовил список выписок

Можно ли добавить список как подготовленный параметр оператора в библиотеке fdb в Python?

Пример:

cur = con.cursor()
list = [1,2,3]
cur.execute("""SELECT * FROM data d WHERE d.field IN ?""", (list,))

Результат:

"Error while preparing SQL statement:")\nDatabaseError: (\'Error while preparing SQL      statement:\\n- SQLCODE: -104\\n- Dynamic SQL Error\\n- SQL error code = -104\\n- Token unknown - line 4, column 33\\n- ?\', -104, 335544569)\n'

Есть ли известные решения? заранее спасибо

3 ответа

Решение

Списки нельзя использовать в качестве значения для параметризованного запроса, вам нужно создать его самостоятельно, динамически создавая запрос с достаточным количеством заполнителей для всех элементов списка или с литеральными значениями из списка.

Попробуй вот так.

cur.execute("""SELECT * FROM data d WHERE d.field IN %s """, (tuple(list), ))

Понимая, что это старый вопрос, будущие посетители должны знать, что ответы, приведенные выше и в комментариях, могут представлять некоторый риск внедрения SQL, если использовать строки в списке, а не только целые числа. Я не создал таблицу для конкретного тестирования приведенного ниже кода, но использовал аналогичный код в других запросах.

К вашему сведению - другие драйверы SQL, такие как pyodbc и psycopg2, используют "% s" в качестве заполнителей, но только "? 'работает для меня, используя FDB.

cur = con.cursor()
list = [1,2,3]

# Create a placeholder list containing a '?' for each element
placeholders = []
for i in list:
    placeholders.append('?')
# Change placeholder list to string of question marks separated by commas
ph_text = ', '.split(placeholders)

# Create sql statement
# Can use format here without risk of SQL injection because it is only ', ' and '?'
sql = """SELECT * FROM data d WHERE d.field IN ({0})""".format(ph_text)

# Execute the statement, passing list items in tuple for fdb to escape (avoid SQL-injection)
# Note that the list is converted to a tuple, 
# whereas the SQL in the question had the list as the first (and only) tuple element
cur.execute(sql, tuple(list))

Да, но ваш синтаксис неправильный, Firebird должен получить

SELECT * FROM data d WHERE d.field IN (1,2,3), поэтому я делал это в прошлом (по памяти)

stmt = "SELECT * FROM data d WHERE d.field IN (" + list + ")" cur.execute (stmt)

Другие вопросы по тегам