【问题标题】:Binding variable to table name with cx_Oracle使用 cx_Oracle 将变量绑定到表名
【发布时间】:2021-06-16 04:42:27
【问题描述】:

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

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

bindvars = {'usertable':usertable}

cursor.execute(query, bindvars)

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

【问题讨论】:

  • 数据库适配器很少支持对任何不是“值”的东西(需要引用的东西)使用参数。要么使用字符串格式(狡猾,你冒着 sql 注入的风险),要么使用像 SQLAlchemy 这样的库,它可以让你使用 Python 代码生成有效的 SQL。
  • @septi:我认为使用表名作为绑定变量是不可能的,你需要创建一个动态语句,通过将表名附加到你的 select 语句。
  • 好的,谢谢,至少我可以停止浪费我的时间了 ;-) 你能添加一个答案,以便我接受吗?

标签: python oracle cx-oracle


【解决方案1】:

也许回复有点晚了,但我 2 天前正在处理同样的事情。

正如 Martjin 所说,解决方案是格式化查询。

query = f'select * from {tableName}'

希望它对我有所帮助。

【讨论】:

    【解决方案2】:

    您不能在 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'])
    

    如果名称无效,您 can capture in cx_Oracle 会引发 ORA-44002,或者如果一切正常,请按照 Martijn 的建议继续。

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

    【讨论】:

      【解决方案3】:

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

      如果您确定您的 usertable 值是正常的(例如,对照现有表名列表检查),则以下方法可行:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-28
        • 1970-01-01
        • 2011-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-28
        相关资源
        最近更新 更多