Предложение sqlite IN, не работающее с необработанным запросом [duplicate]

Войдите в свой mysql, скопируйте и вставьте это:

SHOW VARIABLES LIKE "%version%";

Пример вывода:

    mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+---------------------+
| Variable_name           | Value               |
+-------------------------+---------------------+
| protocol_version        | 10                  |
| version                 | 5.1.73              |
| version_comment         | Source distribution |
| version_compile_machine | i386                |
| version_compile_os      | redhat-linux-gnu    |
+-------------------------+---------------------+
5 rows in set (0.00 sec)
34
задан Clinton Blackmore 21 August 2009 в 04:41
поделиться

5 ответов

Вам нужно правильное число ? s, но это не создает риск инъекции sql:

>>> result_set = c.execute('SELECT * FROM distro WHERE id IN (%s)' %
                           ','.join('?'*len(desired_ids)), desired_ids)
>>> print result_set.fetchall()
[(1, u'Ubuntu'), (2, u'Fedora'), (5, u'SuSE')]
52
ответ дан Alex Martelli 21 August 2018 в 20:41
поделиться
  • 1
    +1 для "наилучшего" решение для создания строки-заполнителя :-) – Ferdinand Beyer 21 August 2009 в 07:39
  • 2
    Есть ли простой способ использовать эти параметры имени? Что-то вроде :id1 :id2 :id3 и т. Д. Я использую это в контексте более крупного запроса с несколькими другими именованными параметрами. – User 11 December 2012 в 00:08
  • 3
    Я приду к этому несколько лет спустя, но мне также нужны именованные параметры. Я только что сделал это: query = "SELECT * FROM my_table WHERE my_param = :my_param AND id IN ({})".format(', '.join(':{}'.format(i) for i in range(len(desired_ids)))) ; params = {'my_param': 'foo'} ; params.update({str(i): id for i, id in enumerate(desired_ids)}) ; result = cursor.execute(query, params) Модуль sqlite3 совершенно доволен такими вещами, как :0, :1, :2 в качестве параметров подстановки строк. (Переполнение стека действительно убивает форматирование кода в комментариях, извините, что так трудно читать.) – geekofalltrades 4 June 2015 в 18:40

Согласно http://www.sqlite.org/limits.html (пункт 9), SQLite не может (по умолчанию) обрабатывать более 999 параметров для запроса, поэтому решения здесь (генерирование нужного списка заполнителей) не удастся, если у вас есть тысячи предметов, которые вы ищете IN. Если это так, вам нужно будет разбить список, затем перебрать его части и объединить результаты самостоятельно.

Если вам не нужны тысячи предметов в вашем IN, то решение Алекса - это способ сделать это (и похоже, как это делает Django).

19
ответ дан cibyr 21 August 2018 в 20:41
поделиться
  • 1
    Хорошо знать. Благодарю. Возможно, мне даже придется пересмотреть мой код. – Clinton Blackmore 17 August 2010 в 16:07
2
ответ дан John Fouhy 21 August 2018 в 20:41
поделиться

Обновление: это работает:

import sqlite3

c = sqlite3.connect(":memory:")
c.execute('CREATE TABLE distro (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)')

for name in 'Ubuntu Fedora Puppy DSL SuSE'.split():
  c.execute('INSERT INTO distro (name) VALUES (?)', ( name,) )

desired_ids = ["1", "2", "5", "47"]
result_set = c.execute('SELECT * FROM distro WHERE id IN (%s)' % ("?," * len(desired_ids))[:-1], desired_ids)
for result in result_set:
  print result

Проблема в том, что у вас его есть? для каждого элемента в списке ввода.

В заявлении ("?," * len(desired_ids))[:-1] делается повторяющаяся строка «?», а затем отсекает последнюю запятую. так что есть один знак вопроса для каждого элемента в желаемых_средствах.

10
ответ дан Mark Rushakoff 21 August 2018 в 20:41
поделиться
  • 1
    Это было отличное объяснение. Спасибо. – Clinton Blackmore 21 August 2009 в 15:24

В случае, если у sqlite есть проблема с длиной запроса sql, неопределенное количество вопросительных знаков может быть каким-то образом для ключения вещей.

0
ответ дан n800s 21 August 2018 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: