2011-01-27 112 views
7

我用pyodbc查詢到SQL Server數據庫SQL操作中使用pyodbc和SQL Server

import datetime 
import pyodbc  
conn = pyodbc.connect("Driver={SQL Server};Server='dbserver',Database='db', 
         TrustedConnection=Yes") 
cursor = conn.cursor() 
ratings = ("PG-13", "PG", "G") 
st_dt = datetime(2010, 1, 1) 
end_dt = datetime(2010, 12, 31) 
cursor.execute("""Select title, director, producer From movies 
       Where rating In ? And release_dt Between ? And ?""", 
       ratings, str(st_dt), str(end_dt)) 

,但我收到以下錯誤。是否需要以不同的方式處理元組參數?有沒有更好的方法來構造這個查詢?

('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Line 9: 
    Incorrect syntax near '@P1'. (170) (SQLExecDirectW); 
    [42000] [Microsoft][ODBC SQL Server Driver][SQL Server] 
    Statement(s) could not be prepared. (8180)") 

UPDATE:

我能得到這個查詢使用字符串格式化操作,因爲它會導致安全問題這是不理想的工作。

import datetime 
import pyodbc  
conn = pyodbc.connect("Driver={SQL Server};Server='dbserver',Database='db', 
         TrustedConnection=Yes") 
cursor = conn.cursor() 
ratings = ("PG-13", "PG", "G") 
st_dt = datetime(2010, 1, 1) 
end_dt = datetime(2010, 12, 31) 
cursor.execute("""Select title, director, producer From movies 
       Where rating In %s And release_dt Between '%s' And '%s'""" % 
       (ratings, st_dt, end_dt)) 

回答

12

不能在使用單一字符串參數的IN()條款參數的多個值。唯一的方法是:

  1. 字符串替換(如你所做的那樣)。

  2. IN (?, ?, . . ., ?)的形式建立參數化查詢,然後爲每個佔位符傳遞單獨的參數。我不是Python到ODBC的專家,但我想象這在Python這樣的語言中特別容易實現。這更安全,因爲您可以獲得參數化的全部價值。

2

問題是你的元組。 ODBC連接期望一個字符串來構造查詢,並且您正在發送一個python元組。請記住,您必須使字符串引用正確。我假設您要查找的收視率數量各不相同。可能有更好的方法,但我的pyodbc往往是簡單明瞭的。

嘗試以下操作:

import datetime 
import pyodbc  
conn = pyodbc.connect("Driver={SQL Server};Server='dbserver',Database='db', 
         TrustedConnection=Yes") 

def List2SQLList(items): 
    sqllist = "%s" % "\",\"".join(items) 
    return sqllist 


cursor = conn.cursor() 
ratings = ("PG-13", "PG", "G") 
st_dt = datetime(2010, 1, 1) 
end_dt = datetime(2010, 12, 31) 
cursor.execute("""Select title, director, producer From movies 
       Where rating In (?) And release_dt Between ? And ?""", 
       List2SQLList(ratings), str(st_dt), str(end_dt)) 
+0

我m仍然收到第一個參數的「語法錯誤」錯誤。 pyodbc可以將列表視爲字符串而不是列表嗎? – user338714 2011-01-27 21:54:57

+0

它的放在整個字符串周圍,看我的編輯 – WombatPM 2011-01-27 22:30:35

11

要在拉里的第二個選項擴展 - 動態創建一個參數字符串,我用成功如下:

placeholders = ",".join("?" * len(code_list)) 
sql = "delete from dbo.Results where RESULT_ID = ? AND CODE IN (%s)" % placeholders 
params = [result_id] 
params.extend(code_list) 
cursor.execute(sql, params) 

給出適當的參數如下SQL:

delete from dbo.Results where RESULT_ID = ? AND CODE IN (?,?,?)