Pyodbc调用带参数的存储过程

Pyodbc Calling a stored procedure with parameters

我一直在尝试带参数调用这个存储过程,但没有成功。我想我已经弄清楚了参数部分,但现在我想我只是简单地错误地调用了存储过程。我试图用他们的错误消息(如下)尽可能地记录我的不同方法。如何调用带参数的存储过程并写入数据框?

尝试 A:使用占位符连接字典中的参数和变量的 %s

params1 = {'mo1_start_date' : '12/30/2019', 'mo1_end_date' : '01/26/2020'}
placeholders = ','.join('?' for i in range(len(params1.values())))  # '?,?'

interconnectmo1 = """exec TNT.dbo.abc \
    @start_date = %(mo1_start_date)s  -- datetime \
  , @end_date = %(mo1_end_date)s    -- datetime \
  , @syscode = NULL           -- varchar(8000)  \
  , @estimate_ids = NULL       -- varchar(8000)""" %placeholders

sqlmo1 = pd.read_sql(interconnectmo1, conn, params1)

错误 A:类型错误:格式需要映射

尝试 B:没有占位符与字典中的参数连接并且?对于变量

params1 = {'mo1_start_date' : '12/30/2019', 'mo1_end_date' : '01/26/2020'}

interconnectmo1 = """exec TNT.dbo.abc\
    @start_date = ? -- datetime \
  , @end_date = ?    -- datetime \
  , @syscode = NULL           -- varchar(8000)  \
  , @estimate_ids = NULL       -- varchar(8000)""" 

sqlmo1 = pd.read_sql(interconnectmo1, conn, params1)

错误 B:[ODBC SQL 服务器驱动程序]COUNT 字段不正确或语法错误 (0) (SQLExecDirectW)

尝试 C:使用占位符连接列表中的参数和变量的 %s

params1 = {'mo1_start_date' : '12/30/2019', 'mo1_end_date' : '01/26/2020'}
paramsmo1=list(params1.values())
placeholders = ','.join('?' for i in range(len(paramsmo1)))  # '?,?'

interconnectmo1 = """exec TNT.dbo.abc\
    @start_date = %(mo1_start_date)s -- datetime \
  , @end_date = %(mo1_end_date)s    -- datetime \
  , @syscode = NULL           -- varchar(8000)  \
  , @estimate_ids = NULL       -- varchar(8000)""" %placeholders

sqlmo1 = pd.read_sql(interconnectmo1, conn, paramsmo1)

错误 C:类型错误:格式需要映射

尝试 D:没有占位符与字典中的参数和变量的 %s 连接

params1 = {'mo1_start_date' : '12/30/2019', 'mo1_end_date' : '01/26/2020'}
interconnectmo1 = """exec TNT.dbo.abc\
    @start_date = "%(mo1_start_date)s" -- datetime \
  , @end_date =  "%(mo1_end_date)s"   -- datetime \
  , @syscode = NULL           -- varchar(8000)  \
  , @estimate_ids = NULL       -- varchar(8000)""" % (params1)

sqlmo1 = pd.read_sql(interconnectmo1, conn, params1)

错误 D:过程或函数需要未提供的参数“@end_date”。

尝试 E:尝试使用光标..

params1 = {'mo1_start_date' : '12/30/2019', 'mo1_end_date' : '01/26/2020'}
csr = conn.cursor()
interconnectmo1 = csr.execute("""exec TNT.dbo.abc \
    @start_date = "%(mo1_start_date)s" -- datetime \
  , @end_date =  "%(mo1_end_date)s"   -- datetime \
  , @syscode = NULL           -- varchar(8000)  \
  , @estimate_ids = NULL       -- varchar(8000)""" % (params1))

csr.execute(interconnectmo1, (params1))

错误 E:过程或函数需要未提供的参数“@end_date”。

我终于让它工作了。此代码有两个问题。

  • 数据类型注释标注。 -- datetime-- varchar(8000) 是个问题。即使我的代码识别了第一个参数,由于这种中断也无法找到第二个参数。
  • 作为参数输入的字典不起作用。我不确定它是否不是一种功能,或者我是否从来没有得到正确的语法来让它工作,但它没有工作。我也研究了绑定参数——没有雪茄。我什至尝试了列表输入,但没有成功。
mo1_start_date='12/30/2019' 
mo1_end_date='1/26/2020' 
interconnectmo1 = """exec TNT.dbo.abc
@start_date = ? , @end_date =  ? , @syscode = NULL , @estimate_ids = NULL""" 
sqlmo1 = pd.read_sql_query(interconnectmo1, conn, params=(mo1_start_date, mo1_end_date))

最直接的方法胜出。完全没有必要把它复杂化。 如果你有一本字典并且不能以这种格式获取你的参数,那么我猜你被迫寻找字典的解决方案。但是对于这个问题,我是一个不必要地创建字典的人。我只是转向了一种更简单的方法来定义我的参数和中提琴。

我希望这对某人有所帮助,因为我花了几天时间和几个代码板才最终放弃我之前的方法来找到这个获胜的!