我有一些我无法理解的问题。我将用户定义的表类型作为参数从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名称的前缀,但这些都没有用。
如果有人能提供帮助,我会非常感激;这让我很生气!我确定这是我看不到的小事!
答案 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();
}
}