如何通过C#将CSV数据传入SQL存储过程实现批量匹配查询
完整实现方案
1. SQL Server 侧准备
1.1 创建用户自定义表类型
该类型用于接收C#传入的单列CSV数据,字段类型、长度需和TestTable的StringColumn保持一致:
CREATE TYPE dbo.StringListType AS TABLE ( StringValue NVARCHAR(200) NOT NULL ) GO
1.2 创建查询存储过程
表值参数必须标注READONLY,通过内连接匹配返回符合要求的记录:
CREATE PROCEDURE dbo.GetMatchedRecords @InputStringList dbo.StringListType READONLY AS BEGIN SET NOCOUNT ON; SELECT t.ID, t.StringColumn, t.AddedDate FROM TestTable t INNER JOIN @InputStringList i ON t.StringColumn = i.StringValue END GO
2. C# 侧实现
推荐使用官方驱动Microsoft.Data.SqlClient,老项目也可以兼容System.Data.SqlClient:
using System; using System.Data; using Microsoft.Data.SqlClient; using System.IO; using System.Linq; public class CsvMatchService { // 替换为实际数据库连接字符串 private const string DbConnString = "Server=你的实例地址;Database=你的库名;Integrated Security=True;TrustServerCertificate=True;"; public DataTable GetMatchResult(string csvFilePath) { // 1. 读取CSV文件,过滤空行、处理首尾空格 var csvRows = File.ReadAllLines(csvFilePath) .Where(row => !string.IsNullOrWhiteSpace(row)) .Select(row => row.Trim()) .ToList(); // 2. 构造和SQL自定义表类型结构一致的DataTable var inputTable = new DataTable(); inputTable.Columns.Add("StringValue", typeof(string)); foreach (var row in csvRows) { inputTable.Rows.Add(row); } // 3. 调用存储过程传递表值参数 using var conn = new SqlConnection(DbConnString); using var cmd = new SqlCommand("dbo.GetMatchedRecords", conn); cmd.CommandType = CommandType.StoredProcedure; // 配置表值参数,TypeName必须和SQL端定义的完全一致 var tvpParam = cmd.Parameters.AddWithValue("@InputStringList", inputTable); tvpParam.SqlDbType = SqlDbType.Structured; tvpParam.TypeName = "dbo.StringListType"; // 4. 读取匹配结果 var result = new DataTable(); conn.Open(); using var reader = cmd.ExecuteReader(); result.Load(reader); return result; } }
注意事项
- 自定义表类型的
StringValue字段属性需和TestTable.StringColumn完全匹配,避免隐式转换导致索引失效 - CSV有特殊编码时,需要给
File.ReadAllLines指定对应编码参数,比如Encoding.UTF8 - 如果CSV包含表头,需要手动跳过第一行再处理数据
- 表值参数的
TypeName属性必须和SQL端定义的[schema].[类型名]完全一致,否则会触发类型不匹配错误
内容的提问来源于stack exchange,提问作者glovescoffee
相关产品推荐
相关产品推荐

