Udt作为SQL Server SP参数通过空

时间:2018-02-13 07:48:25

标签: c# sql-server stored-procedures user-defined-types

我有一些我无法理解的问题。我将用户定义的表类型作为参数从C#传递到SQL Server存储过程,并且一旦到达SP,总是在表中以0行结束。 .NET代码是Framework 4.7,SQL Server托管在Azure中。

SP定义是

CREATE PROCEDURE [dbo].[sp_ImportData]
    @ImportData udt_ImportData READONLY
AS
    INSERT INTO dbo.DEBUG ([Key], [Value])
         SELECT 'IMPORTDATA',
                (SELECT COUNT(1)
                   FROM @ImportData);

    ...
RETURN 0

udt被定义为

CREATE TYPE [dbo].[udt_ImportData] AS TABLE
(
    RecordId INT,
    RecordName NVARCHAR(100)
);

我正在调用SP的代码是

var table = new DataTable();
table.Columns.Add("RecordId", typeof(int));
table.Columns.Add("RecordName", typeof(string));

foreach (DataRow row in data.Rows)
{
    table.Rows.Add(row["RecordId"], row["RecordName"]);
}

using (var connection = new SqlConnection(_connectionString))
{
    var command = new SqlCommand("sp_ImportData", connection);
    SqlParameter tvpParam = command.Parameters.AddWithValue("@ImportData", table);
    tvpParam.SqlDbType = SqlDbType.Structured;
    tvpParam.TypeName = "dbo.udt_ImportData";

    connection.Open();
    command.ExecuteNonQuery();
}

在调试时,我已经检查过表变量中的数据行,然后作为参数值附加。我还在SP中插入了一些调试代码,以便在传入后注销@ImportData表中的行数。这总是为零。我已尝试使用而不是在参数名称中使用@符号,我尝试重命名参数(如果它是我不知道的保留字)。我试过添加和删除“dbo”。在C#中使用udt名称的前缀,但这些都没有用。

如果有人能提供帮助,我会非常感激;这让我很生气!我确定这是我看不到的小事!

1 个答案:

答案 0 :(得分:1)

正如我在评论中写的那样 - 你没有在c#代码中指定命令类型。 CommandType属性的默认值为CommandType.Text - 适合内联sql但不适合存储过程,因此您需要指定CommandType.StoredProcedure。虽然我们在这里,但您不必指定参数的类型名称,而且您确实should avoid using AddWithValue 还有一件事 - SqlCommand也实现了IDisposable接口,所以它也应该在using语句中使用:

using (var connection = new SqlConnection(_connectionString))
{
    using(var command = new SqlCommand("sp_ImportData", connection))
    {
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add("@ImportData", SqlDbType.Structured).Value = table;
        connection.Open();
        command.ExecuteNonQuery();
    }
}