![](/img/trans.png)
[英]Python cx_Oracle binding in SQL query gives ORA-01036: illegal variable name/number
[英]Binding variable to table name with cx_Oracle
我在 Python 中使用 cx_Oracle 并且无法将变量用作表名,就像在这个简单的例子中一样:
query = "select * from some.:usertable.userinfo"
bindvars = {'usertable':usertable}
cursor.execute(query, bindvars)
什么是正确的语法? 当我使用WHERE
... 等时,变量替换工作正常,但不适用于表名。 我想我必须以某种方式将“:usertable”分开......
数据库适配器很少支持对不是“值”(需要引用的东西)的任何东西使用参数。 要么使用字符串格式(狡猾,你冒着 sql 注入的风险)或使用像 SQLAlchemy 这样的库,让你使用 Python 代码生成有效的 SQL。
如果您确定您的usertable
值是正常的(例如,根据现有表名列表进行检查),则以下操作将起作用:
query = 'select * from some.{usertable}.userinfo'.format(usertable=usertable)
您不能在 Oracle 中绑定对象名称,只能绑定文字。 但是,Oracle 确实有一个内置包dbms_assert
,以帮助在使用动态对象名称时防止 SQL 注入。 在您的情况下最有用的函数可能是sql_object_name
,其中:
“... 验证输入参数字符串是现有 SQL 对象的合格 SQL 标识符。”
例如,您可以在 cx_Oracle 中执行以下操作。
object_name = cursor.callfunc('sys.dbms_assert.sql_object_name'
, cx_Oracle.string, ['usertable'])
如果名称无效,它会引发 ORA-44002,您可以在 cx_Oracle 中捕获,或者如果一切正常,请按照 Martijn 的建议继续。
我建议阅读 Oracle 的防止 SQL 注入指南。
也许回复有点晚了,但我两天前也在处理同样的事情。
正如 Martjin 所说,解决方案是格式化查询。
query = f'select * from {tableName}'
希望它可以帮助某人,因为它帮助了我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.