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

SQL Server .bak转INSERT语句报错求助:版本兼容问题

问题分析与修正方案

核心逻辑错误

原代码的根本问题是对SQL Server备份文件(.bak)的性质理解错误:.bak是二进制格式的备份文件,并非包含INSERT语句的文本文件,直接读取二进制内容并尝试解析为SQL语句完全不可行,这也是报错的核心原因。

具体代码错误

  1. 表名拼写错误:创建的临时表是#TempTable,但插入语句写成了INSERT INTO TempTable (D) VALUES (?),遗漏了临时表的#前缀。
  2. 二进制数据处理错误:即便修正表名,后续尝试用decode('utf-8')将备份文件的二进制内容转换为文本完全无效——.bak不是UTF-8编码的文本,会导致乱码或解码失败。
  3. 解析逻辑完全错误:备份文件不存储明文的INSERT语句,试图从中拆分INSERT INTO片段没有任何意义。

正确解决思路

要将高版本SQL Server备份的数据转换为INSERT语句,正确步骤为:

  1. 在安装了SQL Server 2018(或更高版本)的机器上恢复该.bak备份。
  2. 连接到恢复后的数据库,读取所有表的结构和数据,生成对应的INSERT语句。

修正后的Python代码

以下代码实现从已恢复的数据库中读取数据并生成可在SQL Server 2017上执行的INSERT语句:

import pyodbc

# 连接到已恢复备份的SQL Server数据库(需为2018或更高版本)
conn_str = 'DRIVER={SQL Server};Server=myserver;Database=restored_database;Trusted_Connection=True'
conn = pyodbc.connect(conn_str)
cursor = conn.cursor()

# 获取数据库中所有用户表名称
cursor.execute("""
    SELECT TABLE_NAME 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG = 'restored_database'
""")
tables = [row[0] for row in cursor.fetchall()]

for table_name in tables:
    # 获取表的所有列名(按顺序)
    cursor.execute(f"""
        SELECT COLUMN_NAME 
        FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_NAME = '{table_name}' AND TABLE_CATALOG = 'restored_database'
        ORDER BY ORDINAL_POSITION
    """)
    columns = [row[0] for row in cursor.fetchall()]
    columns_str = ', '.join(columns)
    
    # 读取表中所有数据
    cursor.execute(f"SELECT * FROM {table_name}")
    rows = cursor.fetchall()
    
    # 生成INSERT语句
    for row in rows:
        values = []
        for value in row:
            if value is None:
                values.append('NULL')
            elif isinstance(value, str):
                # 转义字符串中的单引号
                escaped_val = value.replace("'", "''")
                values.append(f"'{escaped_val}'")
            elif isinstance(value, (int, float, bool)):
                values.append(str(value))
            elif isinstance(value, bytes):
                # 二进制数据转为十六进制格式
                values.append(f"0x{value.hex()}")
            else:
                # 日期时间等类型转为字符串格式
                values.append(f"'{value}'")
        values_str = ', '.join(values)
        insert_sql = f"INSERT INTO {table_name} ({columns_str}) VALUES ({values_str});"
        print(insert_sql)

cursor.close()
conn.close()

补充说明

  • 需将代码中的restored_database替换为你实际恢复后的数据库名称。
  • 代码已处理常见数据类型,若涉及特殊类型(如地理空间类型),需额外扩展处理逻辑。
  • 生成INSERT语句前,需确保SQL Server 2017的目标数据库已创建好对应的表结构(可从恢复后的数据库导出建表语句)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:07:07