我正在使用 TVP,并且正在尝试将数据表作为 TVP 传递给存储过程。当命令尝试 时ExecuteNonQuery()
,它会引发错误:
操作数类型冲突:datetime2 与 int 不兼容。表值参数“@tvpPermitWork”的数据不符合参数的表类型。
我使用可视化工具检查了数据表,发现所有数据都是正确的。我现在被卡住了,我没有时间将其更改为具有单个参数的存储过程。
非常感谢任何有关如何解决此问题的建议。
我正在使用 TVP,并且正在尝试将数据表作为 TVP 传递给存储过程。当命令尝试 时ExecuteNonQuery()
,它会引发错误:
操作数类型冲突:datetime2 与 int 不兼容。表值参数“@tvpPermitWork”的数据不符合参数的表类型。
我使用可视化工具检查了数据表,发现所有数据都是正确的。我现在被卡住了,我没有时间将其更改为具有单个参数的存储过程。
非常感谢任何有关如何解决此问题的建议。
我已经找到了这个问题的解决方案。
您需要在 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
}
这是 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')
如果表值参数未按照 SQL TVP 列顺序传递,有时会发生这种情况。
它应该在 .NET 和 SQL 中具有相同的顺序
[id] [int] NULL,
[appStatus] [varchar](10) NULL,
[lodgedBy] [varchar](10) NULL,
。网
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 中传递参数时,它必须具有与表值 fn 相同的参数顺序
如果没有看到您的代码,很难确切知道发生了什么,但作为一个快速猜测,您是否设置了SqlParameter.SqlDbType = SqlDbType.Structured
, 和SqlParameter.TypeName = "YourTableType"
?
如果是这样,生成的 T-SQL 是什么样的(您可以使用 SQL Profiler 看到它)?
你的表类型是如何声明的?--CREATE TYPE YourTableType as TABLE ( ... )
你的存储过程是如何声明的?--CREATE PROC ... @arg YourTableType READONLY ... AS ...
您的 DataTable 是如何配置的?它应该包括以下内容:
yourDataTable.Columns.Add("columnName", typeof(datetime2));