2011-01-27 58 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 (?,?,?)