2017-02-21 16 views
1

Я пытаюсь передать неизвестное количество параметров SQL Server в python 3.6. Вот мой код с использованием pypyodbc:Python - передать список как params в SQL, плюс больше переменных

cursor = cnxn.cursor() 
theargs= ['1033286869','1053474957','1063654630','1104116235','1104910306','JASON'] 

thesql = """SELECT * 
      FROM BI_DUPLICATES_STAGE_0 
      WHERE DUP_ID IN (?, ?, ?, ?, ?) 
      AND FRST_NM = ? 
     """ 
cursor.execute(thesql, theargs) 
resultset = cursor.fetchall() 

Это работает. Тем не менее, я никогда не знаю, сколько DUP_ID у меня будет. Я видел несколько примеров использования списка, но если у меня есть другая переменная, такая как этот случай, FRST_NM, то я не могу просто использовать список.

Итак, если кто-то может предоставить простой пример наличия списка (переменной длины) и другой переменной и как заставить SQL работать, я бы очень признателен! Я не обязан использовать pypyodbc, если это проблема, и есть другой способ сделать это.

ОБНОВЛЕНИЕ: Благодарим за красиво отформатированный ответ. Только один быстрый вопрос. Я все еще немного неясно, как я форматировать 2 списка, если я должен был производить что-то вроде: SELECT * FROM BI_DUPLICATES_STAGE_0 WHERE DUP_ID IN (1033286869, 1053474957, 1063654630, 1104116235, 1104910306) AND MID_NM IN ('SMITH','JON') AND FRST_NM = 'JASON'

Без хорошей форме присоединиться, у меня есть некоторый беспорядок, как это: SELECT * FROM BI_DUPLICATES_STAGE_0 WHERE DUP_ID IN (?,?,?,?,?) AND MID_NM IN (?,?) AND FRST_NM = ?

Как бы я формат список в два раза рекомендуется? Имея в виду, я не буду знать, как долго каждый список (ID и MID_NM) на самом деле будет.

+0

* У меня есть некоторый беспорядок, как это * ... почему этот запрос беспорядок? Это подготовленный оператор для параметризованного запроса. – Parfait

ответ

2

Рассмотрит форматирование строки для динамического построения ? заполнителей по длине списков, theargs и другие_аргументов. Обратите внимание, что фамилия должна быть в конце списка параметров, чтобы соответствовать последнему ? placeholder. После этого здания подготовленного заявления, перейти к cursor.execute() со значениями Param:

theargs= ['1033286869','1053474957','1063654630','1104116235','1104910306'] 
otherargs = ['SMITH','JON'] 
lastarg = ['JASON'] 
allargs = theargs + otherargs + lastarg 

thesql = """SELECT * 
      FROM BI_DUPLICATES_STAGE_0 
      WHERE DUP_ID IN ({}) 
      AND MID_NM IN ({}) 
      AND FRST_NM = ? 
     """.format(",".join(['?' for i in range(len(theargs))]), 
        ",".join(['?' for i in range(len(otherargs))]))  
print(thesql) 

# SELECT * 
#    FROM BI_DUPLICATES_STAGE_0 
#    WHERE DUP_ID IN (?,?,?,?,?) 
#    AND MID_NM IN (?,?) 
#    AND FRST_NM = ? 

cursor.execute(thesql, allargs) 
+0

Интересно! Если мое предложение WHERE было чем-то вроде: WHERE id IN (1,2,3) И othervalue IN ('a', 'b', 'c') AND name = 'Bob' был бы умный способ обработки нескольких списков неизвестной длины, которую я не вижу? Я просто удивлен, что нет простого метода IN (@list) для передачи параметров :) – sniperd

+0

Вам нужно будет форматировать дважды для обоих списков. SQL - это декларативный язык. Итак, как только объявляются таблица, столбец, переменная, даже предложения, такие как 'WHERE' или' GROUP BY' или 'JOIN', они являются неизменными. Следовательно, он не может динамически меняться на каждое условие. Python может динамически строить строку, но после ее создания SQL обрабатывает один вызов. – Parfait

+0

Большое спасибо за ответ. Я обновил этот вопрос с небольшим продолжением. Я немного не понимаю, как я буду форматировать дважды для обоих списков :) – sniperd