2017-02-21 65 views
1

我試圖在python 3.6中將未知數量的參數傳遞給SQL Server。這裏是我使用pypyodbc的代碼:Python - 將參數列表傳遞給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() 

This works。但是,我不知道我會有多少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值其它。請注意姓氏應該在參數列表的末尾,以對應最後的?的放置者。一旦完成建設準備好的語句,傳遞給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)AND othervalue IN('a','b','c')AND name ='Bob'會有一種聰明的方式來處理多個列表我沒有看到的未知長度?我很驚訝沒有一種簡單的IN(@list)參數方式來傳遞東西:) – sniperd

+0

您需要爲兩個列表格式化兩次。 SQL是聲明性語言。因此,只要聲明瞭表,列,變量,甚至子句像WHERE或GROUP BY或JOIN,它就是不可變的。因此,它不能根據條件動態改變。 Python可以動態構建字符串,但是一旦構建,SQL就會在一次調用中處理。 – Parfait

+0

非常感謝你的回答。我已經用一個小的後續更新了這個問題。我有點不清楚,我將如何格式化兩個列表:) – sniperd