如何使用 C# 和 SQL 将表值参数传递给用户定义的数据表

Posted

技术标签:

【中文标题】如何使用 C# 和 SQL 将表值参数传递给用户定义的数据表【英文标题】:How to pass table value parameter to user defined data table using C# and SQL 【发布时间】:2019-05-14 23:16:47 【问题描述】:

下面是我的存储过程和我的 C# 代码。目前,我的行数是 1000+,但是当我执行 tvp.Rows.Count 时我得到 90 我相信我的 for 循环并没有真正正确地填充所有内容。这是我的代码 sn-p 下面。请注意,数据表没有填充我在 SQL Server 中的表。

存储过程:

ALTER PROCEDURE [dbo].[TableName] 
    @dt AS dbo.DataTableAsType READONLY   
AS
BEGIN
   INSERT INTO dbo.[DataTableAsType] ([Column names]) --There are 89 column names
       SELECT
           ([ColumnNames])
       FROM 
           @dt
END

第二个存储过程:

    @totalRecords INT OUTPUT
INSERT INTO dbo.tablename1 
FROM dbo.tablename2

SELECT @totalRecords = COUNT(*) 
FROM dbo.[tableName2]

C#代码:

public void InsertDataTableAF2CSV(string ext)

    DataTable tvp = new DataTable();
tvp = ReadFile(filename, "", null);

using (StreamReader sr = new StreamReader(filename))
    
        //this assume the first record is filled with the column names   
        //if (headerRowHasBeenSkipped)
        string headerValue = sr.ReadLine();

        string[] headers = sr.ReadLine().Split(',');
        foreach (string header in headers)
        
            tvp.Columns.Add(header);
        
        while (!sr.EndOfStream)
        
            string[] rows = sr.ReadLine().Split(',');
            //Create a new row
            DataRow dr = tvp.NewRow();
            for (int i = 0; i < headers.Length; i++)
            
                dr[i] = rows[i];
            
            tvp.Rows.Add(dr);
            // Console.WriteLine(tvp);
                  
      

  // Passing a table-valued parameter to a stored procedure
    using (SqlConnection con = new SqlConnection(connection name))
    
        connection.Open();
        // Execute the cmd
        // Configure the command and parameter. 
        SqlCommand cmd = new SqlCommand("dbo.storedprocedure", connection);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandTimeout = 5000;

        // SqlParameter tvparam = cmd.Parameters.AddWithValue("@dt", tvp);

        // Create a DataTable with the modified rows.  
        DataTable addedCategories = tvp.GetChanges(DataRowState.Added);

        // these next lines are important to map the C# DataTable object to the correct SQL User Defined Type
        SqlParameter parameter = new SqlParameter("@dt", SqlDbType.Structured)
                
                    //TypeName = "dbo.DataTableAsType",
                    TypeName = "dbo.importDataTable",
                    Value = tvp
                ;                                   

        cmd.ExecuteNonQuery();
        con.Close();
    

【问题讨论】:

试试这个***.com/questions/12320594/… 这条线看起来很可疑:tvp= ReadFile(filename, " ", null);。那不是把数据表换成你刚刚加载的那个吗? Passing datatable to a stored procedure的可能重复 您正在循环遍历为[89] 定义的数组,并在每次迭代中添加一个数据行。如果数组是列的列表,那么这是对数组的滥用。 我试图构建一个 for 循环来将我的 89 列及其值添加到这些列中。我有超过 3000 多行数据。我该如何纠正它? 【参考方案1】:

在 tvp 中,您要添加 90 行,因此行数应仅为 90。见下文 - 您已将其迭代为 arr.length 并且数组长度仅为 90。

       for (int i = 0; i <= arr.Length; i++)

【讨论】:

对,所以我有 80 多列,但我有 3000 多行数据,这就是为什么我认为我的 for 循环不正确? 我应该为 (int i = 0; i 从这里获取想法 - ***.com/questions/1050112/… @Guarav 看起来与我正在做的类似,我正在上传一个 CSV 文件,将参数传递给存储过程,但我假设我的 for 循环是错误的?你是这么说的吗?当我查看对象“tvp”时,我可以看到行数为 3000+,但“arr”为 90 行数。

以上是关于如何使用 C# 和 SQL 将表值参数传递给用户定义的数据表的主要内容,如果未能解决你的问题,请参考以下文章

如何从.net代码将表值参数传递给存储过程

将表值参数传递给存储过程

将表变量作为参数传递给表值函数

使用 PetaPoco 将表值参数传递给存储过程

将表值参数传递给具有不同字段数的存储过程

SQL Server存储过程中使用表值作为输入参数示例