Search code examples
sql-serverwinformsliststored-proceduressqlclient

Inserting list records in database with stored procedures


I have a list of records inserting into a SQL Server database using a stored procedure. Currently I am doing it this way but is there any better way?

I am inserting 100-200 rows per/sec on peak hours of my app. The stored procedure only gets the values and inserts the new row

    public void InsertRecords(List<stRecord> records)
    {
        foreach (var item in records)
        {
            if (CheckforDuplicateRecord(item) == false)
            {
                using (con = new SqlConnection(connectionString))
                {
                    con.Open();

                    SqlCommand cmd = new    SqlCommand(StoredProcedures.Service_Insert_record.ToString(), con);
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add("@item1", SqlDbType.NChar);
                    cmd.Parameters.Add("@item2", SqlDbType.NChar);

                    cmd.Parameters[0].Value = item.localUsername;
                    cmd.Parameters[1].Value = item.BetfairUsername;


                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (Exception exp)
                    {
                        throw exp;
                    }
                }
            }
        }
    }

Solution

  • This is exactly what table-valued parameters are for - you can pass your list in one shot.

    In SQL Server:

    CREATE TYPE dbo.Usernames AS TABLE
    (
      localUsername   NVARCHAR(32),
      BetfairUsername NVARCHAR(32)
    );
    GO
    
    CREATE PROCEDURE dbo.Service_Insert_MultipleRows
      @u AS dbo.Usernames READONLY
    AS
    BEGIN
      SET NOCOUNT ON;
    
      INSERT INTO dbo.DestinationTable(localUsername, BetfairUsername)
        SELECT localUsername, BetfairUsername FROM @u;
    END
    GO
    

    Now in C#:

    DataTable tvp = new DataTable();
    tvp.Columns.Add(new DataColumn("localUsername"));
    tvp.Columns.Add(new DataColumn("BetfairUsername"));
    
    foreach(var item in records)
    { 
        tvp.Rows.Add(item.localUsername, item.BetfairUsername); 
    }
    
    using (con)
    {
        SqlCommand cmd = new SqlCommand("Service_Insert_MultipleRows", con);
        cmd.CommandType = CommandType.StoredProcedure;
        SqlParameter tvparam = cmd.Parameters.AddWithValue("@u", tvp);
        tvparam.SqlDbType = SqlDbType.Structured;
        con.Open();
        cmd.ExecuteNonQuery();
    }