使用cx_Oracle将变量绑定到表名

时间:2012-10-29 15:24:27

标签: python oracle cx-oracle

我在Python中使用cx_Oracle并且无法将变量用作表名,就像在这个简单的例子中一样:

query = "select * from some.:usertable.userinfo"

bindvars = {'usertable':usertable}

cursor.execute(query, bindvars)

正确的语法是什么?当我使用WHERE ...等但不使用表名时,变量替代工作正常。我想我必须以某种方式将“:usertable”分开......

2 个答案:

答案 0 :(得分:1)

数据库适配器很少支持将参数用于任何非“值”的东西(需要引用的东西)。要么使用字符串格式化(狡猾,你冒着sql注入的风险),要么使用类似SQLAlchemy的库,让你使用Python代码生成有效的SQL。

如果您确定您的usertable值是合理的(例如,根据现有表名列表进行检查),则以下内容将起作用:

query = 'select * from some.{usertable}.userinfo'.format(usertable=usertable)

答案 1 :(得分:1)

您无法在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,如果名称无效,你can capture in cx_Oracle,或者如果一切正常,就像Martijn建议的那样继续。

我建议阅读Oracle guarding against SQL injection指南。