【问题标题】:ADO.Net Table-Valued Parameter (TVP): Operand type clash: datetime2 is incompatible with intADO.Net 表值参数 (TVP):操作数类型冲突:datetime2 与 int 不兼容
【发布时间】:2011-12-01 02:50:31
【问题描述】:

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

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

我使用可视化工具检查了数据表,发现所有数据都是正确的。我现在卡住了,我没有时间将其更改为具有单个参数的存储过程。

非常感谢任何有关如何解决此问题的建议。

【问题讨论】:

    标签: vb.net sql-server-2008 ado.net table-valued-parameters


    【解决方案1】:

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

    您需要在 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
    }
    

    【讨论】:

    • 在这个问题上卡了几个小时,谢谢!顺便说一句,如果您从对象动态生成数据表,您还可以通过 metadatatoken 对属性进行排序: (typeof(T).GetProperties().OrderBy(x=>x.MetadataToken)).ToArray();这样一来,列的顺序将与您键入类属性的顺序相同。
    • 刚刚遇到这个错误,这就是我的解决方案。谁会猜到对于 TVP,列顺序比列名更重要?
    【解决方案2】:

    这是 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')
    

    【讨论】:

    • 太棒了!我浪费了一个多小时试图弄清楚我的数据类型出了什么问题。我从未想过列的顺序:)
    • 想补充一点,如果您使用的是 DataTable 并且您的列设置顺序与类型不匹配,您将遇到相同的错误。
    【解决方案3】:

    如果表值参数未按照 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中传递参数时,它必须具有与表值fn相同的参数顺序

    【讨论】:

      【解决方案4】:

      如果不查看您的代码,很难确切知道发生了什么,但作为一个快速猜测,您是否设置了 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));
      

      【讨论】:

      • 感谢瑞克的回答。我确实这样做了,但问题是基础表列已更改,但表变量未更改,导致不匹配。
      猜你喜欢
      • 2012-06-03
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 2019-10-31
      • 2016-07-09
      • 1970-01-01
      相关资源
      最近更新 更多