Python cx_Oracle 绑定变量
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 绑定变量有三种不同的方法 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})
备注
为什么你的代码可以工作?
让我们试着理解这里发生了什么:
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
我是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 绑定变量有三种不同的方法 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})
备注
为什么你的代码可以工作?
让我们试着理解这里发生了什么:
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