当前位置: 首页 > 面试题库 >

Python cx_Oracle绑定变量

长孙谦
2023-03-14
问题内容

我是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将理解它期望一个变量。这是一个命名变量,由name链接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支持传递命令。



 类似资料:
  • Rust 通过静态类型确保类型安全。变量绑定可以在声明变量时标注类型。不过在多数情况下,编译器能够 从字面内容推导出变量的类型,大大减少了标注类型的负担。 使用 let 绑定操作可以将值(像具体数据)绑定到变量中。 fn main() { let an_integer = 1u32; let a_boolean = true; let unit = (); // 将

  • 变量绑定默认是不可变的,但加上 mut 修饰语后变量就可以改变。 fn main() { let _immutable_binding = 1; let mut mutable_binding = 1; println!("Before mutation: {}", mutable_binding); // 正确代码 mutable_binding += 1

  • 事实上每一个非“Hello World” Rust 程序都用了变量绑定。他们将一些值绑定到一个名字上,这样可以在之后使用他们。let被用来声明一个绑定,像这样: fn main() { let x = 5; } 在每个例子中都写上fn main() {有点冗长,所以之后我们将省略它。如果你是一路看过来的,确保你写了main()函数,而不是省略不写。否则,你将得到一个错误。 模式(Patt

  • 问题内容: 我的FXML注入有问题。据我所知,我已经设置了程序,但似乎缺少了一些东西。我的代码如下: 主要: 控制器: FXML文件: 识别我正在注入 noteTree,sp和newNoteButton的字段 。但是,当我尝试将项目加载到树形视图时,我得到了NPE。我确认使用if语句表明我的3个字段是。堆栈跟踪如下: 事实证明我和我的功能都可以通过。 谁能指出我缺少/做错了什么? 问题答案: 您试

  • 如何使用雪花存储过程将current_date()bind变量插入到表中 创建或替换过程abc(“p_message_id”浮点数、“p_theater”字符串、“p_month”字符串、“p_message”字符串、“p_message”字符串、“p_start_date”字符串、“p_end_date”字符串、“p_action”字符串、“p_msg_type”字符串、“p_logged_us

  • Rust 语言可以先声明变量绑定,后面才将它们初始化。但是这种情况用得很少,因为这样很可能导致使用未 初始的变量。 fn main() { // 声明一个变量绑定 let a_binding; { let x = 2; // 初始化一个绑定 a_binding = x * x; } println!("a bi