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

如何避免C#中SqlBulkCopy向SQL Server导入时的小数舍入问题?

问题分析与解决

当前遇到的小数被舍入问题,核心源于两个关键问题:

  • 原始CSV读取代码存在逻辑错误,导致数据读取不完整
  • DataTable未明确指定列类型为字符串,加上目标表可能使用数值类型,引发自动转换导致舍入

具体修正步骤

1. 修复CSV读取的逻辑错误

原代码中foreach循环内定义的col是局部变量,循环结束后仅会添加最后一行数据;同时读取的lines包含表头行,会导致表头被当作数据插入。需要调整读取逻辑,跳过表头并正确遍历每一行数据。

2. 强制DataTable所有列为字符串类型

因为需要保留CSV中的原始值(同一列可能混合文本和小数),必须将DataTable的每一列都设置为string类型,避免.NET自动推断数据类型引发的转换问题。

3. 确认目标表列类型

SQL Server的Mappingtable中所有列必须设置为varchar或nvarchar类型,不能使用数值类型(如int、decimal等),否则即使传入字符串,SQL Server也会自动转换,导致小数舍入或数据丢失。

修正后的完整代码

DataTable csvData = new DataTable();
string csvFilePath = "你的CSV文件路径"; // 替换为实际路径

// 读取表头并创建字符串类型的列
string headline = File.ReadLines(csvFilePath).ElementAt(0);
string[] headerLine = headline.Split(',');
foreach (string header in headerLine)
{
    // 明确指定列类型为字符串
    csvData.Columns.Add(header, typeof(string));
}

// 读取数据行(跳过第一行表头)
string[] lines = File.ReadAllLines(csvFilePath);
for (int i = 1; i < lines.Length; i++)
{
    string line = lines[i];
    string[] cols = line.Split(',');
    // 确保列数匹配,避免索引越界
    if (cols.Length == headerLine.Length)
    {
        csvData.Rows.Add(cols);
    }
}

// 执行批量插入
using (SqlConnection objConn = new SqlConnection(ConfigurationManager.ConnectionStrings["Live"].ConnectionString))
{
    objConn.Open();
    using (SqlBulkCopy objbulkinsert = new SqlBulkCopy(objConn))
    {
        objbulkinsert.DestinationTableName = "Mappingtable";
        // 映射列(确保目标表列名与CSV表头一致)
        foreach (DataColumn column in csvData.Columns)
        {
            objbulkinsert.ColumnMappings.Add(column.ColumnName, column.ColumnName);
        }
        objbulkinsert.BulkCopyTimeout = 0;
        objbulkinsert.WriteToServer(csvData);
    }
}

额外注意事项

  • 如果CSV中包含带逗号的字段(如"abc,def"),直接用Split(',')会拆分错误,建议使用专门的CSV解析库处理复杂CSV格式
  • 验证目标表的列长度是否足够容纳CSV中的最长内容,避免截断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:49:57