Вы неправильно используете привязку.
Существует три разных способа связывания переменных с 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,))
[EDIT]: спасибо @tyler-christian за упоминание о том, что передача dict поддерживается cx_Oracle.
person
ffarquet
schedule
23.11.2015