【问题标题】:Pyodbc: How to pass tuple as query param?Pyodbc:如何将元组作为查询参数传递?
【发布时间】:2018-07-27 15:28:55
【问题描述】:

简要介绍:

这里的想法是从 csv 文件中读取一些数据,并将其用作我的 sql 查询的NOT IN 部分中的列表。我正在使用下面的代码连接到数据库(.mdb)。 注意LP 是我要传递的元组/列表,IRdb 是数据库的路径

constr = r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=' + IRdb
conn = pyodbc.connect(constr, autocommit=True)
cur = conn.cursor()

IRsql='''SELECT IRRPResults.RRPName, IRRPResults.PointName, IRRPResults.RiskPerTime FROM IRRPResults 
WHERE IRRPResults.PointName<>? 
AND IRRPResults.RRPName NOT LIKE ? AND IRRPResults.PointName NOT IN ?'''

cur.execute(IRsql,('Total',r'Conn%',LP))

问题:

除了执行语句(在我添加NOT IN 部分之前确实有效)之外,一切都很好。我尝试将LP 作为字符串、元组和列表传递,但似乎没有任何效果。我收到以下错误

pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access Driver] In operator without () in query expression 'IRRPResults.PointName<>Pa_RaM000 AND IRRPResults.RRPName NOT LIKE Pa_RaM001 AND IRRPResults.PointName NOT IN Pa_RaM002'. (-3100) (SQLExecDirectW)")

任何帮助将不胜感激。

【问题讨论】:

    标签: python sql ms-access pyodbc


    【解决方案1】:

    对于任何感兴趣的人,或者对于那些在 2 年后阅读此书并遇到相同问题的人,或者我忘记自己做了什么时的未来自我,我已经找到了一两个解决方案。

    第一个解决方法是简单地在 sql 字符串上使用 .format 以在 LP 被传递到执行语句之前直接插入它。

    IRsql='''SELECT IRRPResults.RRPName, IRRPResults.PointName, IRRPResults.RiskPerTime FROM IRRPResults 
    WHERE IRRPResults.PointName<>? 
    AND IRRPResults.RRPName NOT LIKE ? AND IRRPResults.PointName NOT IN {}'''.format(LP)
    
    cur.execute(IRsql,('Total',r'Conn%'))
    

    我从this question 得到的另一个解决方案更加优雅和聪明,因为它构建了一串“?” LP 中每个元素的标记。然后 LP 作为元组/列表传递给执行语句。

    placeholders=','.join('?'*len(LP))
    IRsql='''SELECT IRRPResults.RRPName, IRRPResults.PointName, IRRPResults.RiskPerTime FROM IRRPResults 
    WHERE IRRPResults.PointName<>? 
    AND IRRPResults.RRPName NOT LIKE ? AND IRRPResults.PointName NOT IN ({})'''.format(placeholders)
    
    cur.execute(IRsql,('Total',r'Conn%',*LP))
    

    【讨论】:

    • 我希望我能多次投票。我花了一个多小时来解决这个确切的问题。我想补充一点,如果你想让你的查询是动态的,只包含一个值,那么请记住,带有 len 1 的 dfault 元组看起来像这样:(1,) where '1' 是你想要的SQL 语句中的 in 或 not 参数。结尾带逗号的格式不适用于 SQL,因此另一种方法是将 (1,) 转换为 (1,1),例如:a = [1] if len(a) == 1: a.append(a[0]) b=tuple(a) b
    猜你喜欢
    • 2022-12-15
    • 1970-01-01
    • 2022-01-02
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 2017-07-27
    • 2012-05-24
    相关资源
    最近更新 更多