You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中将含临时表的SQL脚本结果转为DataFrame?

问题解决:从含多语句的SQL文件中提取最后查询结果转为DataFrame

问题背景

我有一个包含注释、临时表及其他内容的SQL文件,需要将文件中最后一条查询语句生成的表转为DataFrame。使用pd.read_sql或pd.read_sql_query执行整个脚本时出现报错,且当文件不含临时表或其他查询时,仅会运行第一条查询后结束,无法获取最后一条结果。

现有环境配置

import pandas as pd
from pandas import DataFrame
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy import text

server = "servername"
database = "databasename"
driver = "driver=ODBC Driver 17 for SQL Server"
engine = create_engine('mssql+pyodbc://' + server + '/' + database + '?trusted_connection=yes&' + driver)
print(engine)

已尝试的方案

方案1:复制粘贴SQL脚本

query = """ 
long SQL 
script copied from 
SQL file 
"""
pd.read_sql(query, engine)

方案2:从文件读取SQL脚本

sql_file = r"C:\Users\username\Documents\Sample Script.sql"

with open(sql_file, 'r') as query:
    query_string = query.read()

pd.read_sql_query(query_string, engine)

遇到的问题

执行上述方案时出现报错:

ResourceClosedError: This result object does not return rows. It has been closed automatically.

当SQL文件不含临时表或其他查询时,两种方案均可成功执行,但仅返回第一条查询的结果,无法获取最后一条查询的输出。

可行解决方案

方法1:修改SQL脚本,确保仅最后一条语句返回结果

在SQL脚本开头添加SET NOCOUNT ON;,该语句会抑制SQL Server返回INSERT/UPDATE/CREATE等操作的行数计数结果,让数据库仅返回最后一条SELECT语句的结果集,这样pd.read_sql就能正确读取目标数据:

修改后的SQL脚本示例:

SET NOCOUNT ON;

-- 这里是注释
CREATE TABLE #TempTable (ID INT, Name VARCHAR(50));
INSERT INTO #TempTable VALUES (1, 'Test');

-- 最后一条查询,返回目标数据
SELECT * FROM #TempTable;

然后使用原有的读取方式即可:

sql_file = r"C:\Users\username\Documents\Sample Script.sql"

with open(sql_file, 'r') as query:
    query_string = query.read()

final_df = pd.read_sql(query_string, engine)

方法2:通过SQLAlchemy手动遍历结果集,提取最后一个结果

如果无法修改SQL脚本,可以通过SQLAlchemy的连接对象执行脚本,遍历所有结果集并提取最后一个转为DataFrame:

from sqlalchemy.exc import ResourceClosedError

sql_file = r"C:\Users\username\Documents\Sample Script.sql"

with open(sql_file, 'r') as query:
    query_string = query.read()

with engine.connect() as conn:
    result = conn.execute(text(query_string))
    all_result_sets = []
    while True:
        try:
            # 将当前结果集转为DataFrame
            df = pd.DataFrame(result.fetchall(), columns=result.keys())
            all_result_sets.append(df)
            # 切换到下一个结果集
            result.nextset()
        except ResourceClosedError:
            # 没有更多结果集时退出循环
            break

# 获取最后一个结果集
final_df = all_result_sets[-1] if all_result_sets else pd.DataFrame()

这种方法会捕获脚本执行过程中所有的结果集,无论前面的语句是否返回计数,都能准确提取最后一条查询的结果。


内容的提问来源于stack exchange,提问作者user32039509403469

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:48:28