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

使用Python将.xls DataFrame插入SQL Server表时遇类型错误求助

问题:使用pandas+pyodbc向SQL Server插入DataFrame时遇到TDS RPC协议错误(float类型无效值)

我正尝试使用pandas和pyodbc库,将从.xls文件读取的Python DataFrame插入SQL Server Management Studio中的现有表,但遇到以下错误:

Traceback (most recent call last):
File "c:/Python/Task1.py", line 27, in cursor.execute('''
pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 16 (""): The supplied value is not a valid instance of data type float. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision. (8023) (SQLExecDirectW)')

以下是我的Python脚本:

import pandas as pd
import pyodbc
#Import the CSV File into the DataFrame
data = pd.read_excel (r'C:\Users\Diego\Documents\1.Laboral\Jas-Ole\Revenue Management\Reservation_stats_REF.xls')
df = pd.DataFrame(data, columns= ['Confirmation_number','Status','Name','Telephone','Adults','Children','Baby', 'Start_date','End_date','Stays','Reservation_date','Property','Covid_payment','Charged_amount','Revenue','Email', 'Origin','Market_code','Transport'])
#Connect Python to SQL Server
conn = pyodbc.connect('Driver={SQL Server};'
'Server=DIEGO\SQLEXPRESS;'
'Database=Auxiliary;'
'Trusted_Connection=yes;')
cursor = conn.cursor()
#Delete a Table data in SQL Server using Python
for row in df.itertuples():
    cursor.execute('''
    DELETE FROM Auxiliary.dbo.Res_statsTEMP
    ''')
#Insert DataFrame to Table
for row in df.itertuples():
    cursor.execute('''
    INSERT INTO Auxiliary.dbo.Res_statsTEMP (Confirmation_number,Status,Name,Telephone,Adults, Children,Baby,Start_date,End_date,Stays,Reservation_date,Property,Covid_payment,Charged_amount, Revenue,Email,Origin,Market_code,Transport)
    VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
    ''',
    row.Confirmation_number, row.Status, row.Name, row.Telephone, row.Adults, row.Children, row.Baby, row.Start_date, row.End_date, row.Stays, row.Reservation_date, row.Property, row.Covid_payment, row.Charged_amount, row.Revenue, row.Email, row.Origin, row.Market_code, row.Transport
    )
conn.commit()

希望能协助解决此问题,提前感谢。


解决方案

先帮你拆解下这个错误:提示里明确说第16个参数对应的值不是有效的float类型。对应你INSERT语句的参数顺序数一下,第16个参数是row.Email——这明显不对劲,Email应该是字符串类型,说明要么是你的SQL表列定义出了问题,要么是列顺序错位导致类型不匹配。下面给你一步步排查和解决的方法:

1. 核对SQL表结构与代码列顺序

先打开SSMS查看Auxiliary.dbo.Res_statsTEMP的表结构:

  • 确认Adults、Children、Charged_amount这类数值列的类型是int或float
  • 确认Email、Name这类文本列的类型是varchar/nvarchar

然后对比你Python代码中INSERT的列顺序和VALUES的参数顺序,必须完全一一对应——哪怕只错一列,都会出现这种类型不匹配的错误。

2. 检查DataFrame数值列的无效值

错误提示还提到要检查源数据的无效值,比如数值精度异常。你可以用pandas快速排查:

# 查看数值列的数据类型
print(df[['Adults','Children','Baby','Stays','Charged_amount','Revenue']].dtypes)
# 找出Adults列中非数值的行
print(df[pd.to_numeric(df['Adults'], errors='coerce').isna()])

如果发现有非数值内容(比如空字符串、特殊符号),可以先做数据清洗:

# 把无效值转为0,或者根据业务逻辑填充/删除
df['Adults'] = pd.to_numeric(df['Adults'], errors='coerce').fillna(0).astype(int)

3. 优化删除数据的逻辑(额外建议)

你现在的删除逻辑是循环每一行都执行一次DELETE,这会重复清空表N次(N是DataFrame行数),完全没必要,改成一次性执行即可:

cursor.execute('DELETE FROM Auxiliary.dbo.Res_statsTEMP')
conn.commit()  # 别忘了提交删除操作

4. 用to_sql简化插入操作

比起手动写INSERT循环,pandas的to_sql方法能自动处理大部分类型映射问题,更高效也更少出错:

from sqlalchemy import create_engine

# 先安装sqlalchemy:pip install sqlalchemy
engine = create_engine('mssql+pyodbc://DIEGO\SQLEXPRESS/Auxiliary?driver=SQL+Server+Native+Client+11.0&trusted_connection=yes')

# 清空表
with engine.connect() as conn:
    conn.execute('DELETE FROM Res_statsTEMP')
    conn.commit()

# 插入数据
df.to_sql('Res_statsTEMP', engine, schema='dbo', if_exists='append', index=False)

优先排查列顺序和表结构的匹配问题,这是这类错误最常见的诱因,祝你顺利解决~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:08:11