您滥用了绑定。
可以通过三种不同的方式将变量与 cx_Oracle 绑定see here :
1) 通过将元组传递给 SQL 语句编号变量 :
sql = "select * from sometable where somefield = :1 and otherfield = :2"
cur.execute(sql, (aValue, anotherValue))
2) 通过将关键字参数传递给 SQL 语句带有命名变量 :
sql = "select * from sometable where somefield = :myField and otherfield = :anotherOne"
cur.execute(sql, myField=aValue, anotherOne=anotherValue)
3)通过将字典传递给SQL语句带有命名变量 :
sql = "select * from sometable where somefield = :myField and otherfield = :anotherOne"
cur.execute(sql, {"myField":aValue, "anotherOne":anotherValue})
Remarks
那么为什么你的代码可以工作呢?
让我们尝试了解这里发生了什么:
bind= {"var" : "ciao"}
sql = "select * from sometable where somefield = :bind and otherfield = :bind"
cur.execute(sql,(bind["var"], bind["var"]))
Oracle 会明白它需要一个变量。这是一个命名变量,通过名称链接bind
。然后,您应该将参数作为命名参数提供,如下所示:
cur.execute(sql, bind="ciao")
或者使用字典,就像这样:
cur.execute(sql, {bind:"ciao"})
然而,当 cx_Oracle 接收一个元组时,它会回退到按数字绑定,就好像您的 SQL 语句是:
sql = "select * from sometable where somefield = :1 and otherfield = :2"
当你经过时bind['var']
两次,这只是字符串"ciao"
。它将两个元组项映射到编号变量:
cur.execute(sql, ("ciao", "ciao"))
这是偶然运行的,但代码非常具有误导性。
具有要绑定的单个值的元组
另请注意,第一个选项需要一个元组。但是,如果您要绑定单个值,则可以使用此表示法创建单个值的元组:
sql = "select * from sometable where somefield = :1"
cur.execute(sql, (aValue,))
[编辑]:感谢 @tyler-christian 提到 cx_Oracle 支持传递字典。