【发布时间】:2020-02-18 08:15:43
【问题描述】:
我编写了一个小工具,可以将数据从 SQL Server 迁移到 Postgres。
为了使事情顺利进行,我使用字符串 concat 快速而肮脏地完成了它,因为我有很多其他问题要解决,而且当时我不想打扰 SQL。不过既然事情都搞定了,我想好好在SQL部门做点事情。
不安全的快速和肮脏的版本:
import pyodbc
# this is the bad example DON'T do this
def getDataFromTable(self,table):
"""
Gets all data from the specified Table.
table -- Table name as string
"""
cursor = self.cursor
SQL = f"""SELECT * FROM {table}""" ## DON'T do this
cursor.execute(SQL)
rows = cursor.fetchall()
records = []
for row in rows:
records.append(list(row))
return records
这工作得很好,但是等待发生的 SQL 注入。
我想构建这样的东西(我省略了未更改的部分):
...
cursor = self.cursor
SQL = f"""SELECT * FROM ?""" # Use parameters insted of string concats
cursor.execute(SQL, table) # pass parameters to the execute method.
rows = cursor.fetchall()
...
这看起来不错的保险箱,但也不起作用。弹出以下错误:
pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die @P1-Tabellenvariable muss deklariert werden. (1087) (SQLExecDirectW); [42000] [Microsoft ][ODBC SQL Server 驱动程序][SQL Server]Anweisung(en) konnte(n) nicht vorbereitet werden. (8180)')
它是德语,但大致翻译为:必须声明表变量,无法准备语句。
如何将变量传递给执行方法以安全地放置标识符?
【问题讨论】:
标签: python sql sql-server pyodbc