首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TVP不符合表类型。

TVP不符合表类型。
EN

Stack Overflow用户
提问于 2014-11-24 17:40:01
回答 4查看 22.9K关注 0票数 5

下面是插入我的数据的函数。

代码语言:javascript
复制
                using (SqlCommand insSwipeDataCommand = connection.CreateCommand())
                {
                    insSwipeDataCommand.Transaction = transaction;
                    insSwipeDataCommand.CommandType = CommandType.StoredProcedure;
                    insSwipeDataCommand.CommandText = "dbo.insSwipeData_sp";

                    SqlParameter attendeeTableParam = insSwipeDataCommand.Parameters.Add("@AttendeeTable", SqlDbType.Structured);
                    attendeeTableParam.Value = this.dataTable;
                    attendeeTableParam.TypeName = "AttendeeTableType";

                    // add orgid parameter
                    insSwipeDataCommand.Parameters.Add("@orgId", SqlDbType.UniqueIdentifier).Value = this.organizationId;
                    insSwipeDataCommand.ExecuteNonQuery();
                }

insSwipeData_sp

代码语言:javascript
复制
create PROC dbo.insSwipeData_sp
(@AttendeeTable         AttendeeTableType READONLY
,@orgId                 UNIQUEIDENTIFIER
)

AS

BEGIN
    SET NOCOUNT ON


    DECLARE @enteredUserId  UNIQUEIDENTIFIER
    SET @enteredUserId = 'xxxxxxxxx-xxxx-xxx-xxxx-xxxxxxxxxx'

    -- Delete old Swipe records
    DELETE FROM dbo.swipeData_tbl
    WHERE orgId = @orgId

    -- CREATE Swipe Records
    INSERT INTO dbo.swipeData_tbl
    (orgId, sdid, rawData, enteredUserId, enteredUtc, manualEntry)
    SELECT @orgId, attendeeId, barcode
          ,@enteredUserId, GETUTCDATE(), 0 -- Consider ( datepart , date ) if date here is needed as NVARCHAR
    FROM @AttendeeTable
    WHERE barcode IS NOT NULL and LTRIM(RTRIM(barcode)) <> '';
END

下面是我的AttendeeTableType模式的图像。

这是我的this.datatable的图片,我用它来做attendeeTableParam

insSwipeDataCommand.ExecuteNonQuery();行中,我得到以下错误。

表值参数"@AttendeeTable“的数据不符合参数的表类型。

EN

回答 4

Stack Overflow用户

发布于 2014-11-24 17:58:26

根据错误,您的数据不完全符合表类型。注意“确切”-如果不为列指定类型,则将推断它们,而且它们很容易被错误推断。这里最好的方法是创建一个与表类型定义匹配的表:

代码语言:javascript
复制
var dt = new DataTable();
dt.Columns.Add("firstName", typeof(string)).MaxLength = 100;
dt.Columns.Add("lastName", typeof(string)).MaxLength = 100;
dt.Columns.Add("studentId", typeof(string)).MaxLength = 10;
dt.Columns.Add("email", typeof(string)).MaxLength = 100;
dt.Columns.Add("barcode", typeof(string)).MaxLength = 100;
dt.Columns.Add("dob", typeof(string)).MaxLength = 200;
dt.Columns.Add("major", typeof(string)).MaxLength = 200;
dt.Columns.Add("gender", typeof(string)).MaxLength = 200;
dt.Columns.Add("classCode", typeof(string)).MaxLength = 15;
dt.Columns.Add("currentclassCode", typeof(string)).MaxLength = 15;
dt.Columns.Add("entranceCode", typeof(string)).MaxLength = 15;
dt.Columns.Add("attendeeId", typeof(Guid));

然后,当需要插入数据时,使用.Clone()创建具有正确架构的新表。这样,如果您的类型或长度不匹配,它将被捕捉到客户端。

还有一种不依赖于将表定义嵌入到应用程序中的方法,即从数据库中获取表定义。这有其优点和缺点--它需要额外的往返到数据库,如果类型或列不匹配,很难发现应用程序逻辑中的错误,但它确实为您提供了更改类型的额外灵活性,而无需更改应用程序(例如,添加一个新的可空列)。

代码语言:javascript
复制
var dt = new DataTable();
using (var connection = new SqlConnection(...)) {
    connection.Open();
    using (var command = new SqlCommand()) {
        command.Connection = connection;
        command.CommandText = "DECLARE @t dbo.AttendeeTableType; SELECT * FROM @t;"
        using (var reader = command.ExecuteReader()) {
            dt.Load(reader);
        }
    }
}

显然,您可能希望缓存这个和.Clone()的结果,而不是对涉及表类型参数的每个命令进行缓存。

票数 9
EN

Stack Overflow用户

发布于 2015-03-13 14:51:51

当我搜索类似的问题时,我到达了这个页面,但是没有一个回复对我有帮助。经过一些头晕之后,我发现出现了错误,以防从代码中传递的数据表有一些不符合TVP类型规范的数据。

例如,如果定义了以下类型:

代码语言:javascript
复制
CREATE TYPE EmployeeType AS TABLE 
(
    EmpID BigInt, EmpName VARCHAR(100)
)

并且假设要传递的数据表有(比方说)一个有超过100个字符的EmpName,则生成“*不符合表类型”错误。

这解决了我的问题。希望它也能帮助到别人。

票数 3
EN

Stack Overflow用户

发布于 2022-01-11 13:26:18

尽管的回答帮助我解决了一个难题,但这个错误还是出现了。

这是我学到的东西;

作为表值param创建和传递的Datatable应该与sql中定义的表值类型中字段的顺序/顺序相对应。

因此,如果您的表类型如下所示:

代码语言:javascript
复制
CREATE TYPE [dbo].[tvp_mytabletype] AS TABLE(
    [ID] BIGINT,
    [AddressCode] BIGINT,
    [Address] NVARCHAR(200) NOT NULL    
)

然后用完全相同的顺序/顺序定义DT列,如下所示:

代码语言:javascript
复制
DataTable dataTable = new DataTable();

//DataTable definition
dataTable.Columns.Add("ID", typeof(long));
dataTable.Columns.Add("AddressCode", typeof(long));
dataTable.Columns.Add("Address", typeof(string)).MaxLength = 200;  
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27110866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档