首页 > 解决方案 > Pyodbc 调用带参数的存储过程

问题描述

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

尝试 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:TypeError:格式需要映射

尝试 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 Server 驱动程序]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:TypeError:格式需要映射

尝试 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”。

标签: sql-serverpython-3.xstored-procedurespypyodbc

解决方案


我终于让这个工作了。这段代码有两个问题。

  • 数据类型注释标注。-- 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))

最直接的方式获胜。根本没有必要使这复杂化。如果您有字典并且无法以这种格式获取参数,那么我想您将被迫为字典寻找解决方案。但是对于这个问题,我是不必要地创建字典的人。我只是用一种更简单的方式来定义我的参数和中提琴。

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


推荐阅读