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

C#读取XLSX插入SQL Server时IDENTITY列插入错误排查

解决SQL Server表值参数插入IDENTITY列的错误(错误200)

你遇到的这个报错是两个核心问题叠加导致的,咱们一步步拆解清楚:

问题根源分析

  1. 数据类型完全不匹配:你的用户定义表类型(UDT)udtInserimentoDatiExcel里的ID是INT类型的IDENTITY列,但C#代码里却把DataTable的ID列错误定义成了Guid类型——这直接导致表值参数的结构和UDT不兼容,触发了"数据不符合参数表类型"的报错。
  2. IDENTITY列插入规则冲突:即使类型匹配,你也不需要(也不允许)给UDT里的IDENTITY列传递数据——SQL Server会自动为IDENTITY列生成值,手动插入会触发"INSERT into an identity column not allowed on table variables"的限制。

修正方案

咱们需要从C#代码、UDT定义、存储过程三个层面同步调整:

1. 修正C# DataTable定义

去掉错误的Guid类型定义,并且不需要在DataTable中包含IDENTITY列(因为最终目标表的ID会由SQL Server自动生成,不需要从C#端传递):

// 正确定义DataTable,只保留业务字段
DataTable dt = new DataTable();
dt.Columns.Add("PIPPO", typeof(string));
dt.Columns.Add("PLUTO", typeof(string));
dt.Columns.Add("PAPERINO", typeof(string));

// 填充数据时,仅给业务字段赋值,无需处理ID
dt.Rows.Add("A", "B", "C");
dt.Rows.Add("D", "E", "F");

// 表值参数传递逻辑保持不变
SqlCommand sqlcmd = new SqlCommand("InserimentoDatiExcel", sqlcon);
sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.Parameters.AddWithValue("@product", dt);
sqlcon.Open();
sqlcmd.ExecuteNonQuery();

2. 调整用户定义表类型(UDT)

既然不需要从C#传递ID值,直接去掉UDT里的IDENTITY属性和ID列(表值参数只需要承载业务数据):

CREATE TYPE [dbo].[udtInserimentoDatiExcel] AS TABLE(
[PIPPO] [varchar](1) NOT NULL,
[PLUTO] [varchar](1) NOT NULL,
[PAPERINO] [varchar](1) NOT NULL
) GO

3. 更新存储过程

修改INSERT语句,明确指定要插入的字段(避免使用SELECT *,防止后续表结构变化引发问题),让目标表Prova的IDENTITY列自动生成值:

ALTER PROCEDURE [dbo].[InserimentoDatiExcel](@product [udtInserimentoDatiExcel] readonly)
AS
BEGIN
-- 明确排除ID列,由Prova表的IDENTITY自动生成
INSERT INTO Prova (PIPPO, PLUTO, PAPERINO)
SELECT PIPPO, PLUTO, PAPERINO FROM @product
END

补充说明

如果你的Prova表本身的ID就是IDENTITY列,那完全不需要在UDT里定义ID字段——表值参数只需要传递业务数据,目标表的自增ID由SQL Server自动处理,这样既符合IDENTITY列的设计规范,也彻底避免了类型不匹配和插入权限的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:20:28