Python cx_Oracle绑定变量

2024-09-29 20:24:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一个Python新手,在使用bind变量时遇到了问题。如果我执行下面的代码,一切正常。

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。


Tags: 代码fromexecutesqlbindvarwhereprepare
2条回答

@ffarquest说cxúu 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

你误用了装订。

有三种不同的方法可以将变量与cxúu 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 = :my_field and otherfield = :anotherOne"
cur.execute(sql, myField=aValue, anotherOne=anotherValue)

3)通过将字典传递给带有命名变量的SQL语句:

sql = "select * from sometable where somefield = :my_field 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"]))

甲骨文将理解,它期望一个变量。这是一个命名变量,通过名称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提到传递dict是由cxúOracle支持的。

相关问题 更多 >

    热门问题