不是重复的 - 如何打破 apart/iterate Python SQL 声明 WHERE IN, with HUGE list

Not a duplicate- How to break apart/iterate Python SQL statement WHERE IN, with HUGE list

我在执行 SQL 语句时遇到问题,其中我的 IN 语句有大量值。我正在尝试想出一种遍历列表并获得组合结果集的方法。

我当前收到的错误是:[SQL服务器]内部错误:已达到表达式服务限制。请在您的查询中寻找可能复杂的表达式,并尝试简化它们。 (8632) (SQLExecDirectW)')

这是因为我的 IN 列表有 75k 个项目。

我假设这需要以某种方式分块,然后循环?

伪代码

List = 75k items
Chunk_Size = 10000
For i in first Chunk_Size of List
    df.append = SQL results WHERE IN List of 10k items

这将循环 8 次将结果附加到数据帧。 - 我希望能够为测试目的定义“块大小”。

条实码:

import pyodbc, pandas as pd
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};'
                      'SERVER=server;'
                      'DATABASE=db;'
                      'UID=Me;'
                      'PWD=Secret;'
                      'Trusted_Connection=yes;')

list_of_ids = ['1', 'Hello', '3.4', 'xyz5000'] #etc to 75k
params= "', '".join(list_of_ids)
sql = ("SELECT [ItemNumber],[Name],[Part] FROM table1 WHERE Part IN ('{}');".format(params))
sql_query = pd.read_sql_query(sql,conn)

我知道使用格式不好,但我无法让执行语句正常工作。 当我这样做时:

sql_query2 = cursor.execute("SELECT [ItemNumber],[Name],[Part] FROM table1 WHERE Part IN ?;",list_of_ids)

我收到这样的错误:pyodbc.ProgrammingError: ('The SQL contains 1 parameter markers, but 4 parameters were supplied', 'HY000')

想法?提前致谢!


解决方案编辑,使用下面蒂姆的解决方案,我可以通过以下方式完成:

Chunk_Size = 10000
list2 = []
cursor = conn.cursor()

for i in range(0, len(list_of_ids), Chunk_Size):
    params= "', '".join(list_of_ids[i:i+Chunk_Size])
    sql = "SELECT [ItemNumber],[Name],[Part] FROM table1 WHERE Part IN ('{}');".format(params)
    cursor.execute(sql)
    list1 = cursor.fetchall()
    list2.append(list1)

from pandas.core.common import flatten
list3 = list(flatten(list2))
match_df = pd.DataFrame.from_records(list3, columns=['Item Number','Name','Part'])

由于 pyodbc 不支持数组参数,因此除了自己格式化请求之外别无选择。

for i in range(0, len(list_of_ids), Chunk_Size):
    params= "', '".join(list_of_ids[i:i+Chunk_Size])
    sql = "SELECT [ItemNumber],[Name],[Part] FROM table1 WHERE Part IN ('{}');".format(params)
    sql_query = pd.read_sql_query(sql,conn)

您可以通过像这样即时构建集合来允许替换:

for i in range(0, len(list_of_ids), Chunk_Size):
    sublist = list_of_ids[i:i+Chunk_Size]
    sql = "SELECT [ItemNumber],[Name],[Part] FROM table1 WHERE Part IN ({});".format(','.join(['?']*len(sublist)))
    sql_query = pd.read_sql_query(sql,conn,sublist)

有多少部分?获取整个 table 并在 Python 中过滤它会更快吗?