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

使用pyodbc操作SQL Server时特殊字符显示为问号的问题求助

解决pyodbc插入SQL Server特殊字符变为问号的问题

核心原因

特殊字符(如″)丢失是因为字段类型非Unicode或连接未正确处理Unicode编码,SQL Server中varchar是单字节编码,无法存储超出ASCII的字符,会自动替换为?。

具体解决方案

1. 修改表字段为Unicode类型

确保创建表时,所有存储字符串的字段使用nvarchar(max)(推荐)或nchar类型,而非varchar/char。修改你的create_table函数,字段定义示例:

def create_table(cursor, table_name, fields):
    # 生成字段定义:每个字段设为nvarchar(max)
    field_defs = ", ".join([f"[{field}] nvarchar(max)" for field in fields])
    query = f"CREATE TABLE {table_name} ({field_defs})"
    cursor.execute(query)

2. 修正连接字符串,启用Unicode支持

在create_conn函数的连接字符串中添加CHARSET=UTF8,并使用最新的ODBC驱动(如ODBC Driver 17 for SQL Server):

def create_conn():
    conn_str = (
        "DRIVER={ODBC Driver 17 for SQL Server};"
        "SERVER=你的服务器地址;"
        "DATABASE=你的数据库名;"
        "UID=用户名;"
        "PWD=密码;"
        "Encrypt=yes;"
        "TrustServerCertificate=yes;"
        "CHARSET=UTF8"
    )
    cnxn = pyodbc.connect(conn_str)
    cursor = cnxn.cursor()
    return cursor, cnxn

3. 使用参数化查询,避免字符串拼接

你的现有代码通过拼接SQL生成插入语句,不仅有SQL注入风险,还会导致编码处理异常。改用pyodbc的参数化查询:

def insert_record(table_name, op_rec):
    cursor, cnxn = create_conn()
    op_rec = remove_none(op_rec)
    fields = list(op_rec.keys())
    
    if not check_table_exists(cursor, table_name):
        create_table(cursor, table_name, fields)

    # 生成参数化占位符和SQL语句
    placeholders = ", ".join(["?"] * len(fields))
    query = f"INSERT INTO {table_name} ({', '.join(fields)}) VALUES ({placeholders})"
    
    # 直接传入参数,pyodbc会自动处理Unicode编码
    cursor.execute(query, list(op_rec.values()))
    cnxn.commit()  # 注意:pyodbc中用连接对象提交,而非游标
    cursor.close()
    cnxn.close()

4. 验证数据库排序规则

确保数据库/表的排序规则支持Unicode(如Chinese_PRC_CI_AS、SQL_Latin1_General_CP1_CI_AS等),默认排序规则通常无需修改,只要字段类型正确即可。

为什么之前的方法无效

你参考的是MySQL相关的解决方案,SQL Server的字符编码处理逻辑与MySQL完全不同,照搬会导致语法错误,且无法解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:15:32