ADO.Net表值参数(TVP):操作数类型冲突:datetime2与int不兼容。

4
我正在使用TVP,并尝试将数据表作为TVP传递给存储过程。当命令尝试执行 ExecuteNonQuery() 时,它会抛出以下错误:

操作数类型冲突:datetime2与int不兼容。参数“@tvpPermitWork”的表值数据不符合参数的表类型。

我使用可视化工具检查了数据表,发现所有数据都是正确的。然而,我现在遇到了困难,没有时间将其更改为带有单独参数的存储过程。
非常感谢您提供任何修复此问题的建议。
4个回答

8

我找到了解决这个问题的方法。

你需要检查你的TVP和C#代码中匹配的列的顺序

例如,如果你的TVP是这样的:

CREATE TYPE [dbo].[tvp_FinDocContract] AS TABLE(
    [column_1_Id] [uniqueidentifier] NOT NULL,
    [column_2_Id] [uniqueidentifier] NULL,
    [column_3_Id] [datetime] NULL
)

那么创建TVP的C#代码应该像这样:

DataTable tvp = new DataTable();

// The column order is very important
tvp.Columns.Add(new DataColumn("column_1_Id", typeof (Guid)){AllowDBNull = false};
tvp.Columns.Add("column_2_Id", typeof (Guid));
tvp.Columns.Add("column_3_Id", typeof (DateTime));

foreach (var item in ...)
{
    //just populating
}

1
被卡在这里好几个小时了,谢谢!另外,如果您正在从对象动态生成数据表,您还可以通过元数据令牌对属性进行排序:(typeof(T).GetProperties().OrderBy(x=>x.MetadataToken)).ToArray(); 这样,列的顺序将与您键入类属性的顺序相同。 - Sean T
2
我刚遇到了这个错误,这对我来说是解决方案。谁能想到对于 TVP 来说,列的顺序比列名更重要呢? - Sturgus

4

这是一个SQL问题,在.NET中插入表类型时缺少列。你需要使用与表类型相同的顺序创建你的订单,就像样例中所示。

我花了两天时间解决这个问题。

declare @p1 dbo.typeSoftCopyDocument
insert into @p1 values(275,491196,N'000001.tif',1,100,5330900910,'2018-09-06 14:49:18',111111,N'xxx',N'xxxx')

1
太棒了!我浪费了一个多小时来弄清楚我的数据类型有什么问题。列的顺序从未出现在我的脑海中 :) - Maddie
想补充一句,如果你正在使用 DataTable 而且你的列设置顺序与类型不匹配,你会遇到同样的错误。 - abjbhat

2

有时,如果按照SQL TVP列的顺序未传递表值参数,则会出现问题。

.NET和SQL中应该具有相同的排序。

[id] [int] NULL,
[appStatus] [varchar](10) NULL,
[lodgedBy] [varchar](10) NULL,

.NET

objSearch = new AppSearchEN();
objSearch.id= context.Request["AppCat"].ToNullableInteger();
objSearch.appStatus= context.Request["AppStatus"] == "0" ? null : context.Request["AppStatus"];
objSearch.lodgedBy= context.Request["lodgedBy"] == "0" ? null : context.Request["lodgedBy"];

在.NET中传递参数时,参数的顺序必须与表值函数中的顺序相同。


1

没有看到你的代码,很难确切地知道发生了什么,但是作为一个快速猜测,你是否设置了 SqlParameter.SqlDbType = SqlDbType.StructuredSqlParameter.TypeName = "YourTableType"

如果是这样,生成的 T-SQL 是什么样子的(可以通过 SQL Profiler 查看)?

你的表类型是如何声明的?-- CREATE TYPE YourTableType as TABLE ( ... )

你的存储过程是如何声明的?-- CREATE PROC ... @arg YourTableType READONLY ... AS ...

你的 DataTable 是如何配置的?它应该包括类似以下内容:

yourDataTable.Columns.Add("columnName", typeof(datetime2));

谢谢你的回答,Rick。我确实这样做了,但问题是底层表列已更改,但表变量没有更改,导致不匹配。 - Raja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接