繁体   English   中英

使用 cx_Oracle 将变量绑定到表名

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM