[英]Python cx_Oracle bind variables
我是 Python 新手,我在使用绑定变量时遇到了麻烦。 如果我执行下面的代码一切正常。
bind= {"var" : "ciao"}
sql = "select * from sometable where somefield = :bind"
cur.prepare(sql)
cur.execute(sql,bind)
相反,如果我添加另一个绑定变量,我会得到一个错误。
bind= {"var" : "ciao"}
sql = "select * from sometable where somefield = :bind and otherfield = :bind"
cur.prepare(sql)
cur.execute(sql,(bind,bind))
cur.execute(sql,(bind,bind))
Oracle.NotSupportedError: Variable_TypeByValue(): unhandled data
我已经解决了
cur.execute(sql,(bind["var"],bind["var"]))
但我不明白为什么以前的命令不行。
哪个是使用绑定变量的正确方法? 我正在使用 cx_Oracle。
您正在滥用绑定。
使用 cx_Oracle 绑定变量有三种不同的方式,可以在此处看到:
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})
为什么你的代码工作呢?
让我们试着理解这里发生了什么:
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 支持传递字典。
@ffarquest 说 cx_Oracle 不支持使用字典,但事实上,@giovanni-de-ciantis 只是错误地使用了它。
named_params = {'dept_id':50, 'sal':1000}
query1 = cursor.execute(
'SELECT * FROM employees WHERE department_id=:dept_id AND salary>:sal',
named_params
)
或者
query2 = cursor.execute(
'SELECT * FROM employees WHERE department_id=:dept_id AND salary>:sal',
dept_id=50,
sal=1000
)
在给定的示例中,我认为:bind
的第二个引用需要用不同的东西替换,因为它不是按顺序完成的。 此外,重命名变量bind
以摆脱混乱。
bind_dict = {bind:"var" : diff:"ciao"}
sql = "select * from sometable where somefield=:bind and otherfield=:diff"
cur.prepare(sql)
cur.execute(sql, bind_dict )
这篇文章来自 2007 年,表明您可以使用字典: http : //www.oracle.com/technetwork/articles/dsl/prez-python-queries-101587.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.