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

如何合并SQL Server多结果集并导入至Python DataFrame

解决方法

方法1:修改SQL脚本生成单一结果集(推荐)

由于不同表的结构可能存在差异,直接返回多个结果集难以合并,我们可以修改SQL逻辑,把每个表的首行数据转成数据库名-表名-列名-列值的统一格式,用UNION ALL拼接成单一结果集,这样pandas可以直接读取全部数据。

SQL脚本

-- 定义要排除的数据库,用逗号分隔
DECLARE @ExcludedDBs NVARCHAR(MAX) = 'master,model,msdb,tempdb,BizDB1,BizDB2';

EXEC sp_MSforeachdb '
-- 跳过排除的数据库
IF NOT EXISTS (SELECT 1 FROM STRING_SPLIT(''@ExcludedDBs'', '','') WHERE value = ''?'')
BEGIN
    -- 遍历当前数据库下的所有表
    EXEC [?].dbo.sp_MSforeachtable ''
        SELECT 
            DB_NAME() AS DatabaseName,
            ''?'' AS TableName,
            c.name AS ColumnName,
            v.ColumnValue
        FROM (
            -- 获取当前表的首行数据
            SELECT TOP 1 * FROM ?
        ) t
        -- 将行转列,统一格式
        UNPIVOT (
            ColumnValue FOR ColumnName IN (' + STUFF((SELECT ',' + QUOTENAME(name) FROM [?].sys.columns WHERE object_id = OBJECT_ID('?') FOR XML PATH('')), 1, 1, '') + ')
        ) v
        JOIN [?].sys.columns c ON v.ColumnName = QUOTENAME(c.name)
    ''
END
'

Python读取代码

import pyodbc
import pandas as pd

# 替换为你的数据库连接信息
conn_str = (
    r'DRIVER={ODBC Driver 17 for SQL Server};'
    r'SERVER=你的服务器名;'
    r'DATABASE=master;'
    r'UID=你的用户名;'
    r'PWD=你的密码;'
)

with pyodbc.connect(conn_str) as conn:
    sql = """
    DECLARE @ExcludedDBs NVARCHAR(MAX) = 'master,model,msdb,tempdb,BizDB1,BizDB2';

    EXEC sp_MSforeachdb '
    IF NOT EXISTS (SELECT 1 FROM STRING_SPLIT(''@ExcludedDBs'', '','') WHERE value = ''?'')
    BEGIN
        EXEC [?].dbo.sp_MSforeachtable ''
            SELECT 
                DB_NAME() AS DatabaseName,
                ''?'' AS TableName,
                c.name AS ColumnName,
                v.ColumnValue
            FROM (
                SELECT TOP 1 * FROM ?
            ) t
            UNPIVOT (
                ColumnValue FOR ColumnName IN (' + STUFF((SELECT ',' + QUOTENAME(name) FROM [?].sys.columns WHERE object_id = OBJECT_ID('?') FOR XML PATH('')), 1, 1, '') + ')
            ) v
            JOIN [?].sys.columns c ON v.ColumnName = QUOTENAME(c.name)
        ''
    END
    '
    """
    # 直接读取单一结果集
    combined_df = pd.read_sql(sql, conn)

print(combined_df.head())

方法2:Python端遍历所有结果集合并

如果不想修改SQL逻辑,可以通过pyodbc的cursor.nextset()方法遍历所有返回的结果集,逐个转成DataFrame后合并。注意要在SQL中给每个结果集加上数据库名和表名,否则无法区分数据来源。

SQL脚本

DECLARE @ExcludedDBs NVARCHAR(MAX) = 'master,model,msdb,tempdb,BizDB1,BizDB2';

EXEC sp_MSforeachdb '
IF NOT EXISTS (SELECT 1 FROM STRING_SPLIT(''@ExcludedDBs'', '','') WHERE value = ''?'')
BEGIN
    EXEC [?].dbo.sp_MSforeachtable ''
        SELECT 
            DB_NAME() AS DatabaseName,
            ''?'' AS TableName,
            *
        FROM ?
        TOP 1
    ''
END
'

Python合并代码

import pyodbc
import pandas as pd

conn_str = (
    r'DRIVER={ODBC Driver 17 for SQL Server};'
    r'SERVER=你的服务器名;'
    r'DATABASE=master;'
    r'UID=你的用户名;'
    r'PWD=你的密码;'
)

conn = pyodbc.connect(conn_str)
cursor = conn.cursor()

sql = """
DECLARE @ExcludedDBs NVARCHAR(MAX) = 'master,model,msdb,tempdb,BizDB1,BizDB2';

EXEC sp_MSforeachdb '
IF NOT EXISTS (SELECT 1 FROM STRING_SPLIT(''@ExcludedDBs'', '','') WHERE value = ''?'')
BEGIN
    EXEC [?].dbo.sp_MSforeachtable ''
        SELECT 
            DB_NAME() AS DatabaseName,
            ''?'' AS TableName,
            *
        FROM ?
        TOP 1
    ''
END
'
"""
cursor.execute(sql)

dfs = []
while True:
    try:
        # 获取当前结果集的列名
        cols = [col[0] for col in cursor.description]
        # 获取所有行数据
        rows = cursor.fetchall()
        # 转成DataFrame并加入列表
        dfs.append(pd.DataFrame.from_records(rows, columns=cols))
        # 切换到下一个结果集
        cursor.nextset()
    except pyodbc.ProgrammingError:
        # 没有更多结果集时退出循环
        break

# 合并所有DataFrame,缺失列自动填充NaN
combined_df = pd.concat(dfs, ignore_index=True)

# 清理资源
cursor.close()
conn.close()

print(combined_df.head())

注意事项

  • 方法1更高效,适合表数量较多的场景,减少了Python与数据库的交互次数。
  • 方法2会保留每个表的原始结构,合并后DataFrame会包含所有表的列,不存在的列值为NaN。
  • 确保SQL Server版本支持STRING_SPLIT(2016及以上),旧版本需替换为自定义字符串分割函数。
  • 执行存储过程需要足够的数据库权限(如db_owner或等效权限)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:18:10