Pyodbc 调用带参数的存储过程。

我一直在尝试调用这个带参数的存储过程,但没有用。我想我已经明白了参数部分,但现在我认为我只是简单地调用了错误的存储过程。我试着把我的不同方法尽可能地记录下来,并附上它们的错误信息(如下)。如何调用带参数的存储过程并写入数据帧?

尝试A:使用一个占位连接,在字典中使用params,变量使用%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 Driver]COUNT字段不正确或语法错误(0)(SQLExecDirectW)

试试C:使用列表中的params和变量的%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。没有在字典中加入params和变量%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))

最直接的方法胜出了。根本没有必要把这个问题复杂化.如果你有一个字典,却不能以这种格式得到你的参数,那么我想你就不得不为字典找一个解决方案。但是对于这个问题,我是一个不必要的创建字典的人。我只是改用更简单的方式来定义我的参数,然后就可以了。

我希望这对某人有所帮助,因为我花了好几天时间和SEVERAL代码板,终于从我之前的方法中退了出来,找到了这个胜利的方法!

给TA打赏
共{{data.count}}人
人已打赏
未分类

Laravel只从关系中添加一个属性.

2022-9-13 12:50:22

未分类

react toggle在初始状态改变时返回错误的状态。

2022-9-13 13:01:36

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索