【问题标题】:Building SQL query string using table-name as given parameter使用表名作为给定参数构建 SQL 查询字符串
【发布时间】:2022-01-10 19:39:02
【问题描述】:

我正在尝试对 SQL 使用字符串格式。 但是在传递变量时,这些变量会用引号插入并破坏语法。

示例

这里我试图将表名传递给函数。

def see_results(cur, table):
    print("complete")
    cur.execute(''' SELECT * from %s ''', (table,))
    results = cur.fetchall()
    print(results)

问题

如果我将"temp_yellow_pages" 作为参数传递,则生成的查询是:''' SELECT * from "temp_yellow_pages" '''。 这打破了。

我想不出不使用" 的变量table 分配任何东西的方法,因为query = temp_yellow_pages 也会中断。

【问题讨论】:

  • 您不能将表名作为查询参数传递。您必须将其插入到实际的查询字符串中。
  • 根据您使用的库,您可能拥有比f"SELECT * from {table}" 更安全的东西。
  • 如果我将 table 设置为 table = "employee -- drop table employee" 或其他一些基于字符串 concat 的“这里有龙”的 sql 示例怎么办?
  • psycopg2,例如,提供cur.execute(psycopg2.sql.SQL("select * from {}").format(sql.Identifier(table)))。注意这不是str.format,而是一个知道SQL语法的SQL.format方法。
  • 谢谢大家。我认为 f-string 文字可能是唯一的方法,但有兴趣看看是否有其他常见的解决方案。

标签: python sql


【解决方案1】:

字符串构建(容易被 SQL 注入)

什么khelwood means

def selectFrom(table):
    return 'SELECT * FROM ' + table


def see_results(cur, table):
    print("complete")
    cur.execute(selectFrom(table))
    results = cur.fetchall()
    print(results)

甚至直接使用 f-strings cur.execute(f"SELECT * FROM {table}"

但是如果在传递的参数table 中有恶意输入,比如附加的DROPTRUNCATE 语句(SQL 注入)?

查询构建(更安全)

使用支持 SQL 的库(SQL 框架database-frontend),例如 psycopg,您可以使用应用输入验证的安全方法构建 SQL。

查看模块 psycopg2.sql 中的示例,为给定的表参数编写 SQL 语句。

from psycopg2 import sql

cur.execute(
    sql.SQL("SELECT * FROM {} WHERE values IN (%s, %s)")
        .format(sql.Identifier('my_table')),
    [10, 20])

【讨论】:

    猜你喜欢
    • 2021-09-24
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多