使用DataTable和SqlBulkCopy批量导入SQL Server时SqlDecimal报错求助
使用SqlBulkCopy批量导入时的数值类型兼容问题解决
问题复盘
在用DataTable配合SqlBulkCopy批量导入SQL Server数据时,先后遇到两个类型相关的异常:
- 最初误以为是大数值decimal列的兼容问题:.NET的
decimal类型范围小于SQL Server的decimal,超出范围会抛出异常;尝试用SqlDecimal类型列填充DataTable后,执行bulkCopy.WriteToServer(dt);时触发InvalidCastException: Failed to convert parameter value from a SqlDecimal to a Decimal。 - 后续排查确认:问题根源是smallmoney列——将
SqlDecimal存入SQL Server的smallmoney列会触发转换错误,而改用.NET原生decimal存入smallmoney或money列则无异常。
对应解决方案
1. 处理SQL Server大数值decimal列导入
如果需要导入超出.NET decimal范围的SQL Server decimal值,不要直接用SqlDecimal填充DataTable,可以选以下两种方式:
- 字符串中转法:把
SqlDecimal转换为合规的数值字符串,DataTable对应列设为string类型,批量导入时SQL Server会自动完成字符串到decimal的转换(需确保字符串格式正确,且目标列的精度、范围足够容纳该数值)。 - 自定义IDataReader:实现自定义的
IDataReader,直接向SqlBulkCopy返回SqlDecimal类型数据,绕过DataTable的类型限制。
2. 处理SQL Server smallmoney/money列导入
直接使用.NET原生decimal类型填充DataTable的对应列即可,因为smallmoney和money的数值范围完全在.NET decimal的覆盖范围内,不需要使用SqlDecimal,从根源避免类型转换异常。
内容的提问来源于stack exchange,提问作者Alsin
相关产品推荐
相关产品推荐

