在 excel Python 中组装用户生成的 SQL 服务器查询时要寻找什么?

What to look for when assembling user generated SQL Sever query in Python from excel?

我正在使用 Excel 作为用户在 SQL 服务器 Table 中创建、删除和更新条目的表单。然后我通过数据框将此输入输入 Python,并创建一个 SQL 字符串。然后我通过 pyodbc 游标执行它。例如,下面是我如何获得有效且功能正常的更新查询。

    ParamstoPass=len(ClassCheckMark.columns)
    L_Cols=list()
    L_Vals=list()
    tableName=ClassCheckMark[ClassCheckMark.columns[1]][0]
    SQL_Query='update ' + tableName + ' set '
    for i in range(2, ParamstoPass):
        L_Cols.append(ClassCheckMark[ClassCheckMark.columns[i]].name)
        L_Vals.append(ClassCheckMark[ClassCheckMark.columns[i]][0])

    for i in range(1, len(L_Cols)):
        SQL_Query=SQL_Query+'[' + L_Cols[i] +']=' +"'" + str(L_Vals[i]) +"', "

    SQL_Query=SQL_Query[:-2]+' where ID=' + "'" + str(L_Vals[0]) +"'"
    cursor.execute(SQL_Query)
    cnn.commit()
    cnn.close()

但我知道用户可能会在 Excel 中输入一些不需要的字符,这些字符随后会进入查询。

那么验证 python 中的 SQL 字符串的最佳方法是什么?我应该寻找特定字符,如 '\'、"\0"、"\n"、"\r"、"'"、'"'、"\x1a" 吗?或者这个 [= 的最佳行业方法是什么24=]?

而且我意识到,一般来说,这不是实现用户与数据库交互目标的最佳方式,但由于各种限制,我正在采用这种方式。

谢谢。

构建 L_ColsL_Vals 列表后,我建议根据 table 元数据验证列名,构建参数化 SQL 命令,然后执行它.例如:

# test data
L_Cols = ['ID', 'FirstName', 'Photo']
L_Vals = [123, 'bob', None]
tablename = "People"

# validate list of column names
valid_column_names = [x.column_name for x in cursor.columns(tablename).fetchall()]
for col_name in L_Cols:
    if col_name not in valid_column_names:
        raise ValueError("[{0}] is not a valid column name for table [{1}]".format(col_name, tablename))
# build SQL command text
SQL_Query = "UPDATE [" + tablename + "] SET "
SQL_Query += ", ".join("[" + x + "]=?" for x in L_Cols[1:])
SQL_Query += " WHERE [" + L_Cols[0] + "]=?"
print(SQL_Query)  # UPDATE [People] SET [FirstName]=?, [Photo]=? WHERE [ID]=?
# move ID value to the end of the list of parameters
params = L_Vals[1:] + L_Vals[0:1]
print(params)  # ['bob', None, 123]

# (edit by OP)
# as in my case, some elements were of unicode markup, which threw
#   ProgrammingError: ('Invalid parameter type.  param-index=0 
#   param-type=numpy.int64', 'HY105'). 
# May need to add params=[str(x) for x in params]

cursor.execute(SQL_Query, params)