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

如何在SSIS/C#脚本任务中定义文本限定符处理CSV导入?

解决SSIS脚本任务中带引号限定符的CSV解析问题

你的核心问题是现有代码无法区分引号内的逗号和列分隔符,同时未处理字段的引号包裹。以下是两种可靠的解决方案,均适用于SSIS的C#脚本任务:

方案一:使用官方TextFieldParser类(推荐)

Microsoft.VisualBasic.FileIO.TextFieldParser是专门为解析带限定符的CSV设计的工具,能自动处理引号内的分隔符、去除引号,还支持空格修剪。

实现步骤:

  1. 在SSIS脚本任务的项目中,右键点击「引用」→「添加引用」,勾选Microsoft.VisualBasic并确定。
  2. 编写解析与插入代码:
using Microsoft.VisualBasic.FileIO;
using System.IO;
using System.Data.SqlClient;
using System.Linq;

// 假设已获取数据库连接connection、SchemaName、TableName、ColumnList
string line = "2, 2012-02-14, \"David\", \"David does, not, show up \", \"AS\", 22";

using (StringReader sr = new StringReader(line))
using (TextFieldParser parser = new TextFieldParser(sr))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    parser.HasFieldsEnclosedInQuotes = true; // 开启引号限定符支持
    parser.TrimWhiteSpace = true; // 自动去除字段前后空格

    string[] fields = parser.ReadFields();
    if (fields != null && fields.Length > 0)
    {
        // 生成参数化SQL(避免SQL注入,同时解决字段含单引号的问题)
        string placeholders = string.Join(", ", fields.Select((_, idx) => $"@param{idx}"));
        string query = $"INSERT INTO {SchemaName}.[{TableName}] ({ColumnList}) VALUES ({placeholders})";

        using (SqlCommand cmd = new SqlCommand(query, connection))
        {
            for (int i = 0; i < fields.Length; i++)
            {
                // 根据SQL字段类型调整参数类型,这里用AddWithValue做示例
                cmd.Parameters.AddWithValue($"@param{i}", fields[i]);
            }
            cmd.ExecuteNonQuery();
        }
    }
}

方案二:自定义CSV解析逻辑(轻量场景)

如果不想引用额外程序集,可以自己实现简单的解析逻辑,手动判断引号状态来分割字段:

using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;

public static string[] ParseQuotedCsvLine(string line, char delimiter = ',', char quote = '"')
{
    List<string> fields = new List<string>();
    StringBuilder currentField = new StringBuilder();
    bool inQuotes = false;

    foreach (char c in line)
    {
        if (c == quote)
        {
            inQuotes = !inQuotes;
            continue; // 跳过引号字符本身
        }

        if (c == delimiter && !inQuotes)
        {
            // 遇到分隔符且不在引号内,完成当前字段
            fields.Add(currentField.ToString().Trim());
            currentField.Clear();
        }
        else
        {
            currentField.Append(c);
        }
    }

    // 添加最后一个字段
    fields.Add(currentField.ToString().Trim());
    return fields.ToArray();
}

// 使用示例
string line = "2, 2012-02-14, \"David\", \"David does, not, show up \", \"AS\", 22";
string[] fields = ParseQuotedCsvLine(line);

// 同样用参数化SQL插入
string placeholders = string.Join(", ", fields.Select((_, idx) => $"@param{idx}"));
string query = $"INSERT INTO {SchemaName}.[{TableName}] ({ColumnList}) VALUES ({placeholders})";

using (SqlCommand cmd = new SqlCommand(query, connection))
{
    for (int i = 0; i < fields.Length; i++)
    {
        cmd.Parameters.AddWithValue($"@param{i}", fields[i]);
    }
    cmd.ExecuteNonQuery();
}

关键注意事项:

  • 永远不要直接拼接SQL字符串(你的原有写法),会导致SQL注入风险,还会因为字段含单引号引发语法错误,参数化查询是最优选择。
  • TextFieldParser能处理更复杂的边缘情况(比如引号内的转义引号:"He said ""hello"""),自定义逻辑如果需要支持这类场景,还需补充转义处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:10:27