【问题标题】:Python Pyodbc Query fails with substitution param list on .join(['?', list])Python Pyodbc 查询因 .join(['?', list]) 上的替换参数列表而失败
【发布时间】:2020-11-30 09:41:54
【问题描述】:

您好,我正在尝试将选择查询从 python 运行到 sql 服务器。我只需要选择来自脚本中另一个函数的列表的特定文件。我为此编写了这个函数:

def flist_in_psumsdb(config, fnames_set_in_psumsdictlist):
constring = config['db_string']['db_string']
cnxn = pyodbc.connect(constring)
FilesToBeCrunched1000 = list(div_list_into_chunks(list(fnames_set_in_psumsdictlist), 1000))
file_list = set()
for FilesChunks1000 in FilesToBeCrunched1000:
    values_string = ', '.join(['?' for item in FilesChunks1000])
    sqlstring = f"""SELECT LOG FROM {config['db_string']['bd_psums_meta_table']} WHERE LOG IN ({values_string})"""
    # print((FilesChunks1000))
    df = pd.read_sql_query(sqlstring,cnxn)
    file_list.update(set(df.LOG))

但是,当我运行脚本时,我收到以下错误:

 Execution failed on sql 'SELECT LOG FROM [NSGWSAINLINE].[dbo].[bd_psums_meta] WHERE LOG IN (?, ?, ?, ?, ?)

我打印了 values 字符串变量,它给了我这个:

?, ?, ?, ?, ?

现在这很奇怪,因为我认为这是您为参数替换进行联接的方式。更奇怪的是,这个相同的结构适用于我编写的另一个函数,用于从同一个表中删除重复项:

    for FilesChunks1000 in FilesToBeCrunched1000:
    values_string = ', '.join(['?' for item in FilesChunks1000])
    sqlstring = f"""DELETE FROM {config['db_string']['bd_psums_meta_table']} WHERE [LOG] IN ({values_string})"""

这个查询显然有效,虽然当我在这个函数中打印 values_string 时,它也返回了相同的结果

?, ?, ?, ?, ?

那是什么?

【问题讨论】:

    标签: python python-3.x pandas sqlalchemy pyodbc


    【解决方案1】:

    您正在使用“?”参数但不在任何地方提供它们的值

    试试这个

    values_string = ', '.join(["?" for item in FilesChunks1000])
    sqlstring = f"""SELECT LOG FROM {config['db_string']['bd_psums_meta_table']} WHERE LOG IN ({values_string})"""
    df = pd.read_sql_query(sqlstring,cnxn, params=FilesChunks1000)
    file_list.update(set(df.LOG))
    

    【讨论】:

    • 但是为什么它适用于我使用相同格式的其他查询?
    • 这样可以防止sql注入吗?
    • 第二条语句可能有效,因为您可能执行了 cnxn.execute(sqlstrin, FilesChunks1000) 之类的 sqlstring,因为此处还提供了值。在 df.read_sql(sqlstring) 的情况下,您没有在任何地方提供文件名列表
    • 我现在明白了,谢谢!您的方法是否可以防止这些所谓的 sql 注入攻击?
    • 为了避免 sql 注入,你可以使用 "pd.read_sql_query(sqlstring, cnxn, params=FilesChunks1000) "
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多