【问题标题】:Pass a Python list to the ORDER BY clause of a SQL Server query将 Python 列表传递给 SQL Server 查询的 ORDER BY 子句
【发布时间】:2019-05-17 10:51:47
【问题描述】:

我正在尝试将 python 列表传递给 SQL Server 查询。我遇到了 pyobdc 错误问题。

我尝试了以下方法:

# order_by is a list with 80 strings e.g. ['a','b','c', ...]
placeholders = ", ".join(["?"] * len(order_by))
query = """
     SELECT *
     FROM my_table_name
     ORDER BY (""" + placeholders + ")"
cursor.execute(query, order_by)

它给了我一个pyodbc错误:

',' 附近的语法不正确。 (102)

我不知道我在哪里犯了语法错误

【问题讨论】:

  • 像这样连接字符串是 SQL 注入攻击发生的方式。此代码对于 any 数据库 - MySQL、PostgreSQL、Oracle、SQL Server 是错误的。事实上,它在任何这些数据库中都会以同样的方式失败。通常,您应该改用参数化/服务器绑定查询
  • 如果您想找出实际的错误是什么,请检查query 字符串。对于初学者,ORDER BY 中不需要括号。其次,80 列可能指向设计缺陷——表真的 包含更多 列吗?你真的需要全部订购吗?第三,为什么该变量名为 placeholdersORDER BY 子句包含列名,而不是值或参数(只能提供值)
  • 您好,所以ORDER BY列表实际上是从另一个sql插入中获得的,该插入首先检索了同一张表的所有列名
  • 查询字符串是什么? 那是包含语法错误的内容。
  • 这不是设计缺陷,它是从 .csv 文件上传的

标签: python sql-server python-3.x pyodbc


【解决方案1】:

查询参数仅用于传递列,而不是列名称。在需要动态包含对象名称的情况下,您需要使用动态 SQL(字符串替换),例如,如下所示:

schema_name = 'dbo'
table_name = 'Donor'

sql = """\
SELECT QUOTENAME(COLUMN_NAME) 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA=? AND TABLE_NAME=?
ORDER BY ORDINAL_POSITION
"""
crsr.execute(sql, schema_name, table_name)
columns = ', '.join([x[0] for x in crsr.fetchall()])
sql = f"SELECT * FROM [{schema_name}].[{table_name}] ORDER BY {columns}"

print(sql)
# SELECT * FROM [dbo].[Donor] ORDER BY [id], [last_name], [first_name]

【讨论】:

  • 这正是我最终要做的。谢谢你,戈德。
猜你喜欢
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
相关资源
最近更新 更多